React에서는 주로 useState를 사용해 데이터를 다룬다. 상태관리를 통해 우리는 데이터관리를 효율적으로 할 수 있다.
상태로는 크게 지역상태와 전역상태로 나누어 볼 수 있다.
props를 사용해 상위컴포넌트에서 하위 컴포넌트로 데이터를 넘겨주는 것을 지역상태로 볼 수 있다. 특정 위치에서 상태(데이터)를 사용하기 위해 반복적으로 상위 컴포넌트로부터 사용할 컴포넌트 위치까지 반복적으로 데이터를 넘겨주는 것을 props drilling이라고 부른다. 이런 경우 상태(데이터)를 사용하지 않는 컴포넌트도 props로 데이터를 받고 넘겨주는 과정을 반복해야하기 때문에 props가 많아지는 경우 관리가 힘들어질 수 있다.
전역상태의 경우 Redux와 같은 라이브러리를 사용해 상태의 위치 상관없이 어디서든 상태(데이터)를 받아와 사용할 수 있다. 전역상태로 사용되면 좋은 데이터는 로그인 데이터, 웹 내 사용자가 쓰는 설정파일, 테마, 언어 등 여러 컴포넌트간 공유되어야할 데이터이다.
이러한 상태들은 유지보수 관점에서 매우 유용하게 쓰일 수 있다. 따라서 개발자는 상태관리에 대한 고민을 많이 하고 효율적으로 상태를 설계할 필요가 있다.
Recoil은 페이스북에서 만든 상태관리 라이브러리이다.
atom 은 기존의 redux에서 쓰이는 store 와 유사한 개념으로, 하나의 상태를 나타낸다. atom의 값을 변경하면 상태를 사용하고 있는 컴포넌트들이 모두 다시 렌더링된다. atom을 생성하기 위해 어플리케이션에서 고유한 키 값과 디폴트 값을 설정해야한다.
export const isEditState = atom({
key: "isEditState",
default: false,
});
export const accessTokenState = atom({
key: "accessTokenState",
default: "",
});
useRecoilState — 첫 요소가 상태의 값이며, 두번째 요소가 호출되었을 때 주어진 값을 업데이트하는 setter 함수인 튜플을 리턴.(useState와 사용법이 동일하다.)
useRecoilValue — setter 함수 없이 atom의 값을 반환만 한다. 컴포넌트가 상태를 읽을 수만 있게 하고 싶을 때에 사용하는 hook이다.
useSetRecoilState — setter 함수만 반환한다. 컴포넌트가 상태에 읽지 않고 쓰기만 하려고 할 때 사용한다.
React에서는 Context API 를 사용하여 프로젝트 안에서 전역적으로 사용 할 수 있는 값을 관리 할 수 있다.
createContext를 이용해 contextAPI를 생성한다.(_app.tsx)
const [isEdit, setIsEdit] = useState(false);
export const GlobalContext = createContext({
isEdit: false,
setIsEdit: (_: any) => {},
});
return 전체 페이지를 context로 감싸준다..(_app.tsx)
return (
<GlobalContext.Provider
value={{
isEdit,
setIsEdit,
}}
>
<ApolloProvider client={client}>
<Global styles={globalStyles} />
{/* <Layout> */}
<Component {...pageProps} />
{/* </Layout> */}
</ApolloProvider>
</GlobalContext.Provider>
);
}
수정페이지에서 isEdit의 값을 true로 바꿔줌 -> 전역 상태 활용
import { useContext } from "react";
import Write from "../../../../quizsrc/components/units/board/21-write/write.container";
import { GlobalContext } from "../../../_app";
export default function EditPage() {
const { setIsEdit } = useContext(GlobalContext);
setIsEdit(true);
return <Write />;
}
isEdit이라는 데이터를 바로 가져와서 사용 (Write 페이지)
import { useContext } from "react";
import { GlobalContext } from "../../../../../pages/_app";
export default function WriteUI() {
const { isEdit } = useContext(GlobalContext);
return (
<>
<h1>{isEdit ? "수정하기" : "등록하기"}</h1>
</>
);
}
React에서는 redux 라이브러리를 이용해서 상태를 관리할 수 있다. redux는 컴포넌트들과 별개로 store라는 곳에 state를 모아두고 필요할때마다 꺼내 사용한다.
Redux의 경우 가장 인지도가 높고 많이 사용되는 상태관리 라이브러이 이다. 하지만다른 라이브러리들에 비해 구현이 복잡하고 많은 코드를 소모한다는 단점이 있다.
redux에서 상태를 변경하기 위해서 action을 사용한다.
state 변수값을 useState를 이용해 바꾸는 것과 비슷한 원리이다.
1. action은 쉽게말해 주문서이다. action을 이용해 바로 상태가 변경되는 것이 아니다.
2. action을 dispatch()메서드를 사용하여 reducer에 전달한다.
3. reducer는 action으로부터 전달반은 주문서를 확인한 뒤 상태의 값을 변경한다.
SWR은 비동기 작업을 도와주는 React Hooks 라이브러리이다.
SWR(stale-while-revalidate) 데이터를 검증하는 동안 stale(Cache) 데이터를 사용하는 것을 말한다. 쉽게말해 Cache된 데이터를 보여주고, 데이터 요청을 보낸 후, 새롭게 받은 데이터를 보여주는 것이다.
mobx는 상태 관리 라이브러리이다.redux에 비해 사용방식이 간단하다는 장점을 가진다.
mobx의 경우 store에 제한을 두지 않기 때문에 상태관리에 주의가 필요하다.