Tiny Bunny
본문 바로가기
JavaScript/React

React - Recoil(React 상태 관리 라이브러리)

by 내이름효주 2024. 4. 5.
  • React 
    • 장점: 편해~~~~
    • 단점: 공유 데이터는 상위컴포넌트에서 정의해야함
  • Recoil: react 상태관리 라이브러리
    • recoil을 쓰는 경우: 데이터를 유지하고 싶을때? 값을 초기화 시키지 않게 하고 싶을때
    • Atoms: 데이터 상태 단위, Atom이 업데이트됐을 때 해당 Atom을 구독하고 있는 컴포넌트들은 리렌더링 됨
    • 전역으로 고유한 키값을 만든 후 키값을 가지고 컴포넌트에서 useRecoilState로 불러다 씀!
      (useState를 useRecoilState를 만들고 useRecoilState에 적용할 변수를 전역에서 생성(key, default)하고 해당 값을 넘겨줌)
    • 변수만들때 key 이름들은 동일하면 안돼!!!
    • Selector: 파생된 상태의 일부를 나타냄, (key, get, set)값을 가짐
    • AtomFamily: Atom을 한번에 모아서 관리
  • 사용방법 (Codepen)
import {
	RecoilRoot,
	atom,
	useRecoilState
} from "https://cdn.skypack.dev/recoil";
  • 스위칭하는 과정에서 recoil 도입
const page1NoAtom = atom({
  key: 'app/page1NoAtom',
  default: 0,
});

function Page1() {
	const [no, setNo] = useRecoilState(page1NoAtom);

	return (
		<>
			<h3>페이지1</h3>
			<ul>
				<li>페이지 1의 숫자 : {no}</li>
				<li>
					<button onClick={() => setNo(no + 1)}>페이지 1의 숫자 증가</button>
				</li>
				<li>
					<button onClick={() => setNo(no - 1)}>페이지 1의 숫자 감소</button>
				</li>
			</ul>
		</>
	);
}

const page2NoAtom = atom({
  key: 'app/page2NoAtom',
  default: 0,
});

function Page2() {
	const [no, setNo] = useRecoilState(page2NoAtom);
		// 내용 동일
};

function Root() {
	return (
		<RecoilRoot>
			<App />
		</RecoilRoot>
	);
}

ReactDOM.render(<Root />, document.getElementById("root"));

 

  • recoil을 이용한 데이터 보존과 전송 
function Page1() {
	const [no, setNo] = useRecoilState(page1NoAtom);

	return (
		<>
			<h3>페이지1</h3>
			<ul>
				<li>페이지 1의 숫자 : {no}</li>
				<li>
					<button onClick={() => setNo(no + 1)}>증가</button>
				</li>
			</ul>
		</>
	);
}

function Page4() {
	const [no, setNo] = useRecoilState(page1NoAtom);

	return (
		<>
			<h3>페이지4</h3>
			<ul>
				<li>페이지 4의 숫자 : {no}</li>
				<li>
					<button onClick={() => setNo(no + 1)}>증가</button>
				</li>
			</ul>
		</>
	);
}
  • page1NoAtom에 해당하는 값을 function Page4()에 넘겨줌 이런식으로 보관해놓은 데이터를 전달도 가능!
  • atomfamily
const page1NoAtom = atom({
	key: "app/page1NoAtom",
	default: 0
});

const page2NoAtom = atom({
	key: "app/page2NoAtom",
	default: 0
});

const page3NoAtom = atom({
	key: "app/page3NoAtom",
	default: 0
});

const page4NoAtom = atom({
	key: "app/page4NoAtom",
	default: 0
});
  • 각각 변수를 나눠줬는데 이걸 하나로 모아! 
const pageNoAtomFamily = atomFamily({
	key: "app/pageNoAtomFamily",
	default: (no) => 0
});

function Page1() {
	const [no, setNo] = useRecoilState(pageNoAtomFamily(1));

	return (
		<>
			<h3>페이지1</h3>
			<ul>
				<li>페이지 1의 숫자 : {no}</li>
				<li>
					<button onClick={() => setNo(no + 1)}>증가</button>
				</li>
			</ul>
		</>
	);
}

function Page2() {
	const [no, setNo] = useRecoilState(pageNoAtomFamily(2));

	return (
		<>
			<h3>페이지2</h3>
			<ul>
				<li>페이지 2의 숫자 : {no}</li>
				<li>
					<button onClick={() => setNo(no + 1)}>증가</button>
				</li>
			</ul>
		</>
	);
}
  • default 값을 (no)로 넘겨주고(함수형태) useRecoilState(pageNoAtomFamily(1));처럼 각각 다른 변수처럼 넘겨주는 느낌인데
  • 커스텀 훅 도입, 훅에서 atom 활용, 데이터 공유
const pageCountAtom = atom({
	key: "app/pageCountAtom",
	default: 0
});

function usePageCountStatus() { // 커스텀 훅
	const [count, setCount] = useRecoilState(pageCountAtom); 

	const increaseOne = () => setCount(count + 1);
	const decreaseOne = () => setCount(count - 1);
	const increaseTen = () => setCount(count + 10);
	const decreaseTen = () => setCount(count - 10);
	const clear = () => setCount(0);

	return {
		count,
		increaseOne,
		decreaseOne,
		increaseTen,
		decreaseTen,
		clear
	};
}

function Page1() {
	const pageCountStatus = usePageCountStatus();

	return (
		<>
			<h3>페이지1</h3>
			<ul>
				<li>페이지 1의 숫자 : {pageCountStatus.count}</li>
				<li>
					<button onClick={pageCountStatus.increaseOne}>1 증가</button>
					<button onClick={pageCountStatus.decreaseOne}>1 감소</button>
					<button onClick={pageCountStatus.increaseTen}>10 증가</button>
					<button onClick={pageCountStatus.decreaseTen}>10 감소</button>
					<button onClick={pageCountStatus.clear}>초기화</button>
				</li>
			</ul>
		</>
	);
}

function Page2() {
	const pageCountStatus = usePageCountStatus();

	return (
		<>
			<h3>페이지2</h3>
			<ul>
				<li>페이지 2의 숫자 : {pageCountStatus.count}</li>
				<li>
					<button onClick={pageCountStatus.increaseOne}>1 증가</button>
					<button onClick={pageCountStatus.decreaseOne}>1 감소</button>
					<button onClick={pageCountStatus.increaseTen}>10 증가</button>
					<button onClick={pageCountStatus.decreaseTen}>10 감소</button>
					<button onClick={pageCountStatus.clear}>초기화</button>
				</li>
			</ul>
		</>
	);
}
  • recoil 개념을 이용한 숫자 변수 > const pageCountAtom = atom({key: "app/pageCountAtom",default: 0});
  • usePageCountStatus()라는 커스텀 훅을 만들어서 count값을 정의해주고 그 안에 각각 1증가, 1감소, 10증가, 10감소, 초기화함수 생성
  •  각각의 페이지에 위치한 버튼에 커스텀훅으로 만든 함수들을 넣음!
  • 모든 페이지에 숫자를 동일한 값으로 넣어 데이터를 공유함 
  • 훅에서 atomfamily 활용, 각 페이지의 default값 조절
const pageCountAtomFamily = atomFamily({
	key: "app/pageCountAtomFamily",
	default: (pageNo) => pageNo
});

function usePageCountStatus(pageNo) {
	const [count, setCount] = useRecoilState(pageCountAtomFamily(pageNo)); 

	const increaseOne = () => setCount(count + 1);
	const decreaseOne = () => setCount(count - 1);
	const increaseTen = () => setCount(count + 10);
	const decreaseTen = () => setCount(count - 10);
	const clear = () => setCount(0);

	return {
		count,
		increaseOne,
		decreaseOne,
		increaseTen,
		decreaseTen,
		clear
	};
}
  • atomFamily를 이용해서 각각의 디폴트 값을 pageNo로 지정!

'JavaScript > React' 카테고리의 다른 글

React - MUI 라이브러리, forwardRef  (0) 2024.04.05
React - CheckBox  (0) 2024.04.05
React - css변수  (0) 2024.04.03
React - 음식 주문 폼  (0) 2024.04.01
React - 할 일 폼 만들기(6)_삭제, 수정, 커스텀 Hook  (0) 2024.03.30