반응형
recoil
recoil
리액트를 위한 상태 관리 라이브러리.
리코일은 기존의 리덕스와 MobX 같은 상태관리 도구들에 비해 가볍고 유연하게 사용할 수 있도록 페이스북에서 오픈소스로 공개한 라이브러리이다
Atom
Atom은 상태이다. 리액트의 state,props 와 비슷하지만 리덕스의 store의 상태들처럼 구독할 수 있고 Atom의 상태가 변경되면 구독하고 있는 컴포너트들의 다시 랜더링되면서 변경된 Atom의 상태를 공유한다.
Selector
Selector는 atoms나 다른 selectors를 입력으로 받아들이는 순수 함수(pure function)다
쉽게 생각하면 컴포넌트에서 일일이 상태 값들을 컴포넌트끼리 전달하고 관련된 컴포넌트가 렌더링 되는 것이 아니라 한곳에 모아두고 렌더링할 때마다 그 값을 쓰는 컴포넌트만 렌더링 시켜주는 것
간단한 텍스트 추가 앱을 만들어 사용해보자.
- 먼저 리액트 프로젝트를 하나 생성한다.
npx create-react-app recoil
- npm을 이용해 recoil 패키지 설치
npm install recoil
- recoil을 쓰지 않고 만든 것
import React from "react";
import { Counter } from "./Counter";
function App() {
return <Counter />;
}
export default App;
import React, { useState } from "react";
import { View } from "./View";
export function Counter() {
const [inputText, setInputText] = useState("");
const [text, setText] = useState([{ id: 0, text: "리코일" }]);
const changeInputText = (e) => setInputText(e.target.value);
const addText = (e) => {
setText((current) => [
...current,
{ key: current.length + 2, text: inputText },
]);
setInputText("");
};
return (
<>
<input type="text" value={inputText} onChange={changeInputText} />
<button onClick={addText}> + </button>
<ul>
{text.map((object) => (
<View key={object.id} text={object.text} />
))}
</ul>
</>
);
}
import React from "react";
export function View({ text }) {
return <li>{text}</li>;
}
- recoil 상태를 사용하는 컴포넌트는 부모 트리 어딘가에 나타나는 RecoilRoot 가 필요하다. 루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소다. atom과 selector를 생성해 컴포넌트에서 컴포넌트로 props를 전달하지 않고도 상태 값을 쓸 수 있다.
import React from "react";
import { RecoilRoot } from "recoil";
import { Counter } from "./Counter";
function App() {
return (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
}
export default App;
atom.js;
import { atom, selector } from "recoil";
export const textState = atom({
key: "textState",
default: [{ key: 1, text: "리코일" }],
});
export const setTextState = selector({
key: "setTextState",
get: ({ get }) => {
const text = get(textState);
return `마지막에 추가한 텍스트는 ${text[text.length - 1].text}`;
},
});
counter.js;
import React, { useState } from "react";
import { View } from "./View";
import { textState, setTextState } from "./atom";
import { useRecoilState } from "recoil";
import { AnotherComponent } from "./AnotherComponent";
export function Counter() {
const [inputText, setInputText] = useState("");
const [text, setText] = useRecoilState(textState);
const changeInputText = (e) => setInputText(e.target.value);
const addText = (e) => {
setText((current) => [
...current,
{ key: current.length + 2, text: inputText },
]);
setInputText("");
};
return (
<>
<input type="text" value={inputText} onChange={changeInputText} />
<button onClick={addText}> + </button>
<ul>
{text.map((object) => (
<View key={object.id} text={object.text} />
))}
</ul>
{/* AnotherComponet에 props로 값을 전달하지 않아도 쓸 수 있다.*/}
<AnotherComponent />
</>
);
}
AnotherComponent.js;
import React from "react";
import { useRecoilState, useRecoilValue } from "recoil";
import { textState, setTextState } from "./atom";
export function AnotherComponent() {
const text = useRecoilState(textState);
const lastText = useRecoilValue(setTextState);
return (
<>
<hr />
{`텍스트 붙여서 나오기 ${text[0].map((e) => e.text)}`}
<hr />
{lastText}
</>
);
}
반응형
'리액트' 카테고리의 다른 글
리덕스 맛보기 (0) | 2022.02.04 |
---|---|
간단하게 이미지 슬라이드 구현하기 (0) | 2022.02.04 |
(리액트를 다루는 기술) 8장 Hooks (0) | 2021.04.08 |
(리액트를 다루는 기술) 6장 컴포넌트 반복 (0) | 2021.04.01 |
(리액트를 다루는 기술) 5장 ref-dom에 이름 달기 (0) | 2021.03.29 |