Hah-nna / Tech_Interview

0 stars 0 forks source link

React: Hooks - useState #3

Open Hah-nna opened 7 months ago

Hah-nna commented 7 months ago

React

useState

useState란?

const [count, setCount] = useState(0)

state, state management

useState가 상태를 관리하는 상태관리 훅이라고 했는데, 여기서 상태는 무엇이고 상태 관리는 무엇일까?

state

> [props](https://legacy.reactjs.org/docs/components-and-props.html) (short for “properties”) and [state](https://legacy.reactjs.org/docs/state-and-lifecycle.html) are both plain JavaScript objects. While both hold information that influences the output of render, they are different in one important way: props get passed to the component (similar to function parameters) whereas state is managed within the component (similar to variables declared within a function). 리액트 공식홈페이지에서는 props와 state 둘 다 렌더링 결과에 영향을 끼치는 일반 자바스크립트 객체라고 정의함. 즉, 둘 다 컴포넌트의 렌더링에 영향을 미치는 데이터임. props와 state의 차이점은 props는 부모에서 자식컴포넌트로 내려주는 데이터이며, 내려받은 컴포넌트에서 수정이 불가능함 state는 컴포넌트 안에서 관리되는 (함수에서 선언된 변수처럼) 데이터임. useState 같은 훅을 통해 관리되고 사용자의 인터랙션에 따라 변화함 . 즉, state는 사용자와의 인터랙션을 통해 변화하는 데이터임. 예를 들면 좋아요를 누르면 갯수가 변화한다든지, 장바구니에 제품을 담을 때 제품이 추가되고, 삭제할 때는 제품이 삭제되는 등 사용자와의 인터랙션을 통해 상태가 변화하는 것을 볼 수 있음

state management

그렇다면 왜 상태관리가 필요할까?

프로젝트가 커질 수록 상태가 복잡해지기 때문에 효율적으로 상태를 관리하기 위해서 필요함

예를 들어 여러 컴포넌트에서 같은 state를 공유해야하는 일이 생긴다고 가정함.

상위 컴포넌트에서 state를 관리하고 하위 컴포넌트에게 props로 넘겨주는 방식 사용을 사용하게 되는데, 이러한 방식은 복잡성이 증가함. 또한 하위의 하위 컴포넌트에서도 해당 state를 사용해야한다면 props를 계속 내려주어야함(props drilling 발생). 이는 해당 props가 어디서 왔는지 추척하기 어렵게 만듦. 따라서 유지 보수가 어려워짐.

따라서 상태관리 도구를 사용해 상태를 중앙에서 관리하고, 필요한 컴포넌트에게만 제공함으로써 코드의 복잡성을 줄이고 유지보수를 용이하게 할 수 있음

state management tools

**recoil** - 전역 상태관리 라이브러리 - 직관적이고 리덕스에 비해 보일러플레이트가 적음 - 러닝커브가 낮다는 장점 recoil은 atom과 selector를 통해 상태를 관리함 먼저 atom을 정의하고 컴포넌트에서 사용 시 useRecoilState, useSetState 등을 사용해 기존의 리액트에서 상태관리를 하는 것과 비슷하게 사용함. atom 값이 변경되면 해당 atom을 구독하고 있는 모든 컴포넌트가 리렌더링됨. recoil의 데이터 방향은 리액트처럼 단방향. **react-query** - 서버 상태 관리를 할 때 많이 사용 - 직관적이고 서버에서 데이터를 가져오고 캐싱하고 업데이트, 동기화를 하는데 사용 - react-query의 데이터 흐름도 단뱡향 useQuery(fetch)나 useMutation 훅을 사용해 API 호출 정의를 하고 필요에 따라 자동으로 API 호출을 실행함 -> 해당 useQuery나 useMutation을 구독하는 컴포넌트들은 새로운 데이터로 리렌더링됨. 이때 반환된 데이터는 react query가 관리하는 캐시에 저장됨

useState와 useRef의 차이점

가장 큰 차이점은 useState는 상태값을 관리하기 위해 사용되고, 상태가 업데이트될 때마다 컴포넌트가 리렌더링되며, UI에 반영이 됨. 반면 useRef는 컴포넌트의 생애주기동안 계속 유지되며, 값이 변경되어도 컴포넌트가 리렌더링되지 않음.

예시
``` import { useRef, useState } from 'react; import "./styles.css"; export default function App() { const [stateCount, setStateCount] = useState(0); const refCount = useRef(0); return (


useState Count: {stateCount}
useRef Count: {refCount.current}
); } ```

state버튼을 누르면 useState의 stateCount 값이 증가하고, 렌더링되어 변화된 값이 화면에 적용되는 걸 볼 수 있음(해당 상태가 변경될 때마다 컴포넌트가 리렌더링되어 변경된 상태값이 화면에 반영됨)

하지만 ref버튼을 누르면 변경된 값이 화면에 렌더링되고 있지 않음. useRef 내부적으로는 값이 변경되고 있지만 useRef는 current 값이 변경되어도 컴포넌트를 리렌더링하지 않음. 따라서 화면이 리렌더링되지 않으므로 반영이 되고 있지 않을 뿐임.

state 버튼을 다시 눌러 컴포넌트를 리렌더링을 시키면 useRef의 값도 올라감. state가 변경되었을 때, refCount.current의 값도 마찬가지로 화면에 렌더링됨.

useRef는 컴포넌트의 생애주기 동안(언마운트 되기 전까지) 변화하는 값을 가지고 있다가 다른 상태 변경(ex: useState, useReducer 등)으로 인해 컴포넌트가 리렌더링되면 그 시점에서의 최신 refCount.current의 값이 화면에 렌더링됨(useState와 다르게 current의 값이 변화할 때마다 화면 리렌더링x).

useState의 불변성

예시

const [item, setItem] = useState(['apple', 'banana', 'orange'])라는 배열을 가진 state가 있다고 가정함 여기에 'peach'를 추가한다고 했을 때 item.push('peach')를 한다면 직접 변경을 하는 것이기 때문에 리액트는 item 배열의 변화를 알지 못함(변경을 할 떄는 setState를 사용해 이전 상태와는 별개의 새로운 상태를 생성하기 때문) 따라서 불변성을 유지하면서 상태를 변경하려면 리액트에서는 다음과 같이 할 수 있음 ``` setItem([...item, 'peach']) ``` 스프레드 연산자를 사용해 기존 item의 요소들을 새로운 배열에 복사 후 'peach'라는 새로운 요소를 새로운 배열에 추가함. 그러면 기존 item배열은 변하지 않고 기존의 item 배열과는 별개의 새로운 배열이 생성되어 state가 업데이트 됨


정리

useState란?

상태란?

컴포넌트 안에서 관리되고, useState 같은 훅을 통해 관리되며 사용자의 인터랙션에 따라 변화하는 데이터

상태관리란?

state를 props로 내려주는 방식을 사용하면 props drilling이 발생해 코드가 복잡해지고, 유지보수가 어려워짐 -> 상태관리 도구를 사용해 상태를 중앙에서 관리하고 필요한 컴포넌트만 사용하게 하여 코드의 복잡도를 줄이고, 유지보수가 용이하게 함

상태관리 툴

useState와 useRef의 차이점

useState의 불변성

state가 객체나 배열 등의 참조형 데이터인 경우, 기존 상태를 직접 수정하는 것이 아니라 새로운 상태를 생성해주어 불변성을 유지하게 함 -> 불변성을 유지함으로써 React는 상태의 변화를 효율적으로 감지하고 필요한 컴포넌트만을 재렌더링할 수 있음

Hah-nna commented 7 months ago

내용 추가 및 수정 중...

Hah-nna commented 7 months ago

추가 및 수정 완료