-
Week02 리액트/Next.js 기초 3.5 React Hooks (1) - 상태 훅웹개발/React 2023. 12. 31. 16:39
React Hooks는 훅(Hook)을 통해 함수 컴포넌트 안의 상태나 라이프 사이클을 다루기 위한 기능이다.
잘 와닿지 않는데 HTML과 Vanila JS를 사용 할 줄 안다는 가정하에 훅이 무슨 역할인지 이해해보자.
유저가 input을 입력하고 submit버튼을 누르면 유저의 입력값이 나타나는 코드를 작성한다고 가정해보자.
Java script 파일에 작성해야 할 점을 생각해본다면 3가지로 추릴 수 있다.
1. submit버튼 클릭시 input에 들어와 있는 값을 가져와야한다.
2. submit버튼에 클릭 시 어떤 행동을 하라는 (이 경우에는 input값을 가져와 입력값을 출력하는) 이벤트 리스너를 달아야 한다.
3. input값에 들어가 있던 값을 어느 엘리먼트에서 프린트 할 것인지 가져와야 한다.
따라서 document.getElement method를 사용해 여러가지 엘리먼트의 값들을 끌어와야 하고 엘리먼트들이 많아지고 복잡해질 수록 id, class등 관리가 어려워 질 것이다.
React에서는 html 사이에 코드 (변수, 함수) 등을 그대로 넣을 수 있기 때문에 2, 3번은 손쉽게 해결된다. 다만 1, 2번이 문제인데 1번은 상태를 관리하는 useState를 사용한다면 유저가 입력값을 변경할때마다 실시간으로 변경되며 변수에 저장할 수 있다. (useState)
import React, { useState } from 'react'; const App = () => { const [result, setResult] = useState(''); const handleSubmit = (event) => { event.preventDefault(); const inputValue = event.target.inputField.value; setResult(inputValue); }; return ( <div> <form onSubmit={handleSubmit}> <label htmlFor="inputField">Enter your text:</label> <input type="text" id="inputField" name="inputField" required /> <button type="submit">Submit</button> </form> {result && <div>{`You entered: ${result}`}</div>} </div> ); }; export default App;
코드가 이해가 잘 되지 않을 수 있는데 사용된 useState에 대해 설명하고 다시 설명하도록 하겠다.
3.5.1 useState와 useReducer - 상태 훅
"상태" 훅이다. 변수나 Object의 상태 변화를 다룬다. 이때 상태변화란 ? 기본형인 숫자를 예로 들자면 count라는 이름의 변수의 value가 1일 때 우리는 이 변수의 상태를 1이라고한다. count에 1을 더한다면 count=count+1이 되고 이 변화를 상태 변화라한다. 복잡한 경우라면 Object형이 있다. 이름, 전화번호, 주소 등등이 담겨있는 객체에서 특정 값을 변경 시킨다면 이 또한 상태 변화라고 한다.
useState와 useReducer의 큰 차이점을 꼽자면 자료형에 구애받지 않고 다양한 상태변화를 작성할 수 있는가이다.
( 상태 변화 함수를 사용해 상수, 정해진 값으로 바꾸는건 논외로 치자. ex) state값을 1로 변경, "hello"로 변경 )
useState와 useReducer에 대해 알아보며 위의 문장을 이해해보자.
3.5.1 - 1 useState
const [상태변수이름, 업데이트함수이름] = useState(상태 변수의 초깃값)
counter라는 이름을 가진 변수에 초깃값은 0을 주고 어떤 조건 마다 counter+1을 해줘야 한다면.
const [counter, ] =useState(0) 이라고 작성할 수 있다. 업데이트할 함수의 이름은 맘대로 정하는데 일반적으로 set+변수이름으로 정한다. (웹개발이니까 카멜케이스로 쓰자.)
따라서 이렇게 작성할 수 있다.
import { useState } from 'react' const [counter, setCounter] = useState(0);
업데이트 함수를 호출 할 때는 인수에 값을 전달하는 방법과 함수를 전달하는 방법이 있다.
- 값을 전달할 경우
- setCounter(1), setCounter("hello"), setCounter(true) 등 상수 전달
- setCounter(counter+1) 과 같이 counter 변수를 가져와 현재 값을 기준으로 변한 값 전달
- 따라서 이 경우 함수의 인수에 들어간 값 자체가 counter의 값이 된다.
- 함수를 전달 할 경우
- setCounter((prevCounter)=>prevCounter+1)
- 들어가는 함수의 기본인자에는 기존의 counter값이 들어간다. 그리고 이 함수가 return하는 값이 counter의 상태가된다.
따라서 setCounter(counter+1) 과 setCounter((prevCounter) => prevCounter+1))은 같다.
import React, { useState } from 'react'; const App = () => { const [result, setResult] = useState(''); const handleSubmit = (event) => { event.preventDefault(); const inputValue = event.target.inputField.value; setResult(inputValue); }; return ( <div> <form onSubmit={handleSubmit}> <label htmlFor="inputField">Enter your text:</label> <input type="text" id="inputField" name="inputField" required /> <button type="submit">Submit</button> </form> {result && <div>{`You entered: ${result}`}</div>} </div> ); }; export default App;
이제 이 코드를 다시 보면 조금 이해가 새로 될 것이다. useState를 사용해 input filed에 있는 value값을 받아오고 상태를 변경해주면 이후에 <form> 뒤의 result 에서 입력 받은 값을 사용 할 수 있다.
3.5.1 - 2 useReducer
reducer는 현재 상태와 들어오는 action을 기반으로 다음 상태를 결정한다.
사용법을 보자.
const reducer = (현재 상태 변수 , action) => { if(action=='something') return 다음 상태; else return 다음 상태; } const [현재 상태 변수, dispatch] = useReducer(reducer, 초기 상태);
앞서 작성했던 counter+1을 useReducer로 작성해보자.
import { useReducer } from 'react' type Action = 'INCREMENT' | 'RESET' const reducer = (currentCounter: number, action: Action) => { if (action === 'INCREMENT') return currentCounter+1; else return 0; } const Counter = () => { const [ count, dispatch ] = useReducer(reducer, 0); return { <> <p> Count : {count}</p> <button onClick={()=>dispatch('INCREMENT')}>+</button> <button onClick={()=>dispatch('RESET')}>Reset</button> </> } } export default Counter;
Increment reset을 다 useState로 구현하려면 setState자체에 다 달라지는 값들을 넣어줘야 하고 이 경우 코드의 볼륨이 커지면 이해하기 힘들게 된다. 하지만 Reducer를 사용하면 다양한 Action을 다루면서도 한 reducer안에서 관리할 수 있기 때문에 코드의 유지,보수가 쉬워지는 장점이 있다.
혹시 틀린 부분이 있다면 지적해주시면 감사하겠습니다. :)
'웹개발 > React' 카테고리의 다른 글
Week01 리액트/Next.js 기초 3.1-3.4 (0) 2023.12.31 React study 시작 (0) 2023.12.31 - 값을 전달할 경우