React μνκ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬
μν(State)
Reactμμ μν(State)λ μ»΄ν¬λνΈ μμμ λμ μΌλ‘ λ³ν μ μλ λ°μ΄ν°λ₯Ό μλ―Ένλ€. λ³μ, κ°μ²΄, ν¨μ λ± μ΄λ° κ²λ€μ΄ μνκ° λλ€.
μλ₯Ό λ€μ΄, ν¨μ κ°μ κ²½μ°μλ μ¬μ©μκ° λ²νΌμ ν΄λ¦ν λλ§λ€ νλμ λ³μμΈ μ«μλ₯Ό μ¦κ°μν€λ κΈ°λ₯μ΄ λ΄κ²¨μλ ν¨μκ° μλ€λ©΄ κ·Έ ν¨μλ μνκ° λλ€.
μνκ΄λ¦¬ μ΄μ
μμ μ ν리μΌμ΄μ μμλ μ»΄ν¬λνΈ λ΄λΆμμ μνλ₯Ό κ΄λ¦¬νλ κ²μ κ°λ¨νλ€. λνμ μΌλ‘ useStateκ° μλ€. νμ§λ§ μ ν리μΌμ΄μ μ΄ μ»€μ§κ³ μ¬λ¬ μ»΄ν¬λνΈκ° μνΈμμ©ν λ, μν κ΄λ¦¬λ μ μ 볡μ‘ν΄μ§λλ€. λͺ¨λ μ»΄ν¬λνΈμ useStateλ₯Ό μ¬μ©ν μλ μκ³ propsλ‘ μ λ¬νλ κ²μλ νκ³κ° μκΈ° λλ¬Έμ΄λ€.
μλ₯Ό λ€μ΄, μ¬μ©μ μ 보μ λν λ°μ΄ν°κ° λ΄κ²¨μλ μν(state)κ° μλ€. μ΄ μ¬μ©μμ λν μ λ³΄κ° νμν μ»΄ν¬λνΈκ° νμκ°μ , λ‘κ·ΈμΈ λ± μ¬μ©μ μΈμ¦ μ»΄ν¬λνΈμ μκΈ° μ 보λ€μ λ³Ό μ μλ λ§μ΄νμ΄μ§ μ»΄ν¬λνΈκ° μλ€κ³ ν΄λ³΄μ. μ΄ λ μ»΄ν¬λνΈλ λ€λ₯Έ νμ΄μ§λ‘ λΆλ₯λλ μ»΄ν¬λνΈμΈλ° κ΅³μ΄ λ μ€ νλμ μ»΄ν¬λνΈμ useStateλ₯Ό μ¬μ©νμ¬ μ¬μ©μ μ 보μ μνλ₯Ό μ΄κΈ°ννμ¬ λλ¨Έμ§ νλμ μ»΄ν¬λνΈμ propsλ‘ μ λ¬ν μ΄μ κ° μλ€.(Props Drilling λ°©μ§) μλλ©΄ λ μ»΄ν¬λνΈμ κ°μ useStateλ₯Ό μ¬μ©νλ©΄ λμ§ μλ λΌκ³ νλ©΄ κ²°κ΅ μ»΄ν¬λνΈλ€μ΄ μ΄λ£¨μ΄ νλμ νλ‘μ νΈκ° λλλ° νλ‘μ νΈκ° μμ λμ΄ μ΅μ ν ν λλ§λ€ κ° μ»΄ν¬λνΈμ μνλ€μ΄ λ 립μ μ΄κ² λλ©΄ νλ‘μ νΈκ° κΌ¬μ΄λ©΄μ νΌλμ΄ μκΈΈ μ μλ€.
λ°λΌμ μνλ₯Ό κ΄λ¦¬νλ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ λͺ¨λ μ»΄ν¬λνΈλ€μ΄ μ΅μ μνλ₯Ό μ½κ² 곡μ νκ³ μ λ°μ΄νΈν μ μλλ‘ νκΈ° μν΄ μ¬μ©νλ€. κ²°κ΅ μνκ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μΌκ΄λ λ°μ΄ν° κ΄λ¦¬κ° λλ©° μ½λλ κ°μνλλ€. κ·Έλ¦¬κ³ μ¬λ¬ μ»΄ν¬λνΈλ₯Ό μμ νλ λμ μ€μ μν κ΄λ¦¬ μ½λλ§ μμ νλ©΄ λκΈ° λλ¬Έμ μ μ§λ³΄μλ μ©μ΄ν΄μ§λ€.
μνκ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬ - Redux, MobX, Recoil, etc...
ποΈπ¨οΈ Recoil
Recoil μ€μΉ
npm install recoil
npm i recoil
Atom
Recoilμμμ μν(State) λ¨μ
atomμ ν΅ν΄ μνλ₯Ό μ μ₯νλ©΄ μ΄λ€ μ»΄ν¬λνΈμμλ μ½κ³ μΈ μ μλ€.
→ atomμ κ°μ μ½λ μ»΄ν¬λνΈλ€μ μ묡μ μΌλ‘ atomμ ꡬλ (atomμ importνμ¬ atomμ μνλ₯Ό λΆλ¬μ΄)
atomμ ꡬλ νλ λͺ¨λ μ»΄ν¬λνΈλ atomμ μνκ° μ΅μ ν λ λλ§λ€ μ¬ λ λλ§λλ κ²°κ³Όκ° λ°μνλ€.
atomμ μνλ₯Ό μ¬μ© (μ½κΈ°, μμ (μ°κΈ°))νκΈ° μν΄μ useRecoilState() μ¬μ©
// app.ts
import React from 'react';
import {
RecoilRoot,
atom,
selector,
useRecoilState,
useRecoilValue,
} from 'recoil';
const App: React.FC = () => {
return (
<RecoilRoot>
<CharacterCounter />
</RecoilRoot>
);
};
export default App;
// src/atoms/textAtom.ts
import { atom } from 'recoil';
export const textState = atom<string>({
key: 'textState', // keyκ°
default: '', // κΈ°λ³Έ μΈν
(μ΄κΈ°νλ)κ°
});
// ./CharacterCounter.tsx
import React from 'react';
import TextInput from './TextInput';
import CharacterCount from './CharacterCount';
const CharacterCounter: React.FC = () => {
return (
<div>
<TextInput />
<CharacterCount />
</div>
);
};
export default CharacterCounter;
// ./TextInput.tsx
import React, { ChangeEvent } from 'react';
import { useRecoilState } from 'recoil';
import { textState } from './atoms/textAtom';
const TextInput: React.FC = () => {
const [text, setText] = useRecoilState(textState);
const onChange = (event: ChangeEvent<HTMLInputElement>) => {
setText(event.target.value);
};
return (
<div>
<input type="text" value={text} onChange={onChange} />
<br />
Echo: {text}
</div>
);
};
export default TextInput;
Selector
νμλ μν(derived state) : μνμ λ³ν
μ¦, νμλ μνλ₯Ό μ΄λ€ λ°©λ²μΌλ‘λ μ£Όμ΄μ§ μνλ₯Ό μμ νλ μμ ν¨μμ μ λ¬λ μνμ κ²°κ³Όλ¬Ό
→ μνλ₯Ό μμ , κ°κ³΅λ±μ νλ returnκ°μ΄ μ‘΄μ¬νλ ν¨μ
ν¨μμ κ°μ λΆλ¬μ μ½κΈ° μν΄μ useRecoilValue() μ¬μ©
// src/atoms/textAtom.ts
...
export const charCountState = selector<number>({
key: 'charCountState',
get: ({ get }) => {
const text = get(textState);
return text.length;
},
});
// ./CharacterCount.tsx
import React from 'react';
import { useRecoilValue } from 'recoil';
import { charCountState } from './atoms/textAtom';
const CharacterCount: React.FC = () => {
const count = useRecoilValue(charCountState);
return <>Character Count: {count}</>;
};
export default CharacterCount;
useRecoilState() : writableν μν → useStateμ²λΌ setν¨μ μ‘΄μ¬ (μμ μ¦, settingμ΄ κ°λ₯νκΈ° λλ¬Έ)
useRecoilValue : read only μν → λ³μ, μμμ μ΄κΈ°ν νμ¬ λΆλ¬μ€κΈ°λ§ κ°λ₯ (λ°λΌμ returnκ°μ΄ μλ ν¨μμ μ£Όλ‘ μ¬μ©)