Today, What I learned?
ํ์ ์คํฌ๋ฆฝํธ์ ๋ฆฌ๋์ค ํดํท์ผ๋ก ๋ฆฌํฉํ ๋ง ํ๋ ํฌ๋๋ฆฌ์คํธ๋ฅผ ๋ฆฌ์ฝ์ผ๋ก ํ๋ฒ ๋ !.. ๋ฆฌํฉํ ๋งํด๋ณด์๋ค.
(์ตํ๋ณด๊ธฐ์ ํฌ๋๋ฆฌ์คํธ๋งํ ๊ฒ์ด ์๋ค..)
๋ฆฌ์ฝ์ผ์ ๋ํด ๊ฐ๋ตํ๊ฒ ์ ๋ฆฌํด๋ณด๊ณ ๋ฆฌํฉํ ๋ง ๊ณผ์ ์ ๊ธฐ๋กํ๋ค.
Recoil
๋ฆฌ์ฝ์ผ์ facebook์์ ์ถ์ํ ๋ฆฌ์กํธ๋ฅผ ์ํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
๋ง์ด๋ค ์ฌ์ฉํ๋ ๋ฆฌ๋์ค๋ณด๋ค ๋ณด์ผ๋ฌ ํ๋ ์ดํธ๊ฐ ์ ๊ณ ,
์ก์
, ๋ฆฌ๋์, ๋์คํจ์น.. ์ ๊ฐ์ด ์์์ผ ํ ๊ธฐ๋ณธ ๊ฐ๋
์ด ๋ง์ ๋ฆฌ๋์ค์ ๋นํด ์๋์ ์ผ๋ก ์ฝ๊ฒ ์ตํ ์ ์๋ค.
๋ ์ฌ์ฉ๋ฐฉ๋ฒ์ด useState
ํ
์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋ฏํ๋ค.
๋ฆฌ๋์ค์์ ๋น๋๊ธฐ ์์
์ ์ํด Redux-thunk
๋ Redux-saga
๊ฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ข ๋ ์ด๋ ต๋ค๊ณ ํ ์ ์๋๋ฐ, ๋ฆฌ์ฝ์ผ์์๋ ๋ด์ฅ๋ Selector
๋ฅผ ํตํด ๋น๋๊ธฐ ๋ก์ง์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
๊ธฐ๋ณธ์ ์ธ Recoil ๊ฐ๋
RecoilRoot
๋ฆฌ๋์ค์ Provider ๊ฐ์ ๊ฐ๋ ์ด๋ค. ๋ฃจํธ ์ปดํฌ๋ํธ์ ๊ฐ์ธ์ค๋ค.
Atom
์ํ์ ์ผ๋ถ๋ค. atom์ ๊ตฌ๋
ํ๋ ์ปดํฌ๋ํธ๋ ์ด๋์์๋ atom์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ ์ ์๋ค.atom()
์ผ๋ก ์ ์ธ์ ํ๋๋ฐ, key
์ default
๊ฐ์ ํ์์ ์ผ๋ก ์ ์ธํด์ผ ํ๋ค.
import { atom } from 'recoil';
export const textState = atom({
key: 'textState', // atom์ ์๋ณํ๋ ์ ์ญ์ ์ผ๋ก ๊ณ ์ ํ ๊ฐ
default: '', // ์ด๊น๊ฐ. ๋ค๋ฅธ atom์ด๋ selector๋ ๋ค์ด์ฌ ์ ์๋ค.
});
useRecoilState()
์ปดํฌ๋ํธ์์ useState()๋ฅผ ์ฐ๋ฏ์ด atom์ ์ฝ๊ณ ์ฐ๋ ๋ฐ์ ์ฌ์ฉํ๋ ํ
.
์ด ํ
์ธ์๋ atom์ ์ฝ์ ๋๋ง ์ฌ์ฉํ๋ useRecoilValue()
, ์ธ ๋๋ง ์ฌ์ฉํ๋ useSetRecoilState()
ํ
๋ฑ์ด ์๋ค.
์ํ๊ฐ๊ณผ setter ํจ์๋ฅผ ๋ฆฌํดํ๋ค. atom ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์ปดํฌ๋ํธ๊ฐ ์๋์ ์ผ๋ก ๋ฆฌ๋ ๋๋ง ๋๋ค.
import React from 'react';
import { useRecoilState } from 'recoil';
import { textState } from './atoms';
const CharacterCoutner = () => {
const [text, setText] = useRecoilState(textState);
const onChange = (e) => setText(e.target.value);
return (
<div>
<input type="text" value={text} onChange={onChange} />
<div>{text}</div>
</div>
);
};
export default CharacterCoutner;
๊ฐ๋จํ ๊ฐ๋
์ ์ด ์ ๋๋ก ์ดํด๋ณด๊ณ Selector ๋ฑ์ ๊ฐ๋
์ ๊ณต์๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด ๋ณด์!...
https://recoiljs.org/ko/docs/introduction/installation
์ด์ ๋ณธ๊ฒฉ์ ์ธ ๋ฆฌํฉํ ๋ง ๊ณผ์ .
Recoil ์ค์น
๋ฆฌ์ฝ์ผ์ ์ค์นํด ์ค๋ค.
npm install recoil
yarn add recoil
Recoil ์ค์
index.tsx
์ ๊ธฐ์กด์ redux provider ๋์ ์ RecoilRoot
๋ก ๊ฐ์ธ์ค๋ค.
import App from './App';
import { RecoilRoot } from 'recoil';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<RecoilRoot>
<App />
</RecoilRoot>
);
State ์ค์
recoil ํด๋ ์์ state๋ฅผ ๋ฃ์ ํ์ผ์ ์์ฑํ๋ค.
ํ์
์คํฌ๋ฆฝํธ ํ๋ก์ ํธ์ด๊ธฐ ๋๋ฌธ์ atom์ ํ์
์ ๋ณ๋๋ก ์ ์ธํด ์ฃผ์๋ค.
์ฒซ ๋ ๋๋ง์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ด๊ฐ ์์ ๊ฐ์ด ํ์ํด์ default์ ๋ฐฐ์ด ๊ฐ์ ๊ฐ๋ค์ ๋ฃ์ด์ฃผ์๋ค.
import { atom } from 'recoil';
import { TodoType } from '../components/todoForm/TodoForm';
import { v4 as uuid } from 'uuid';
export const todoState = atom<TodoType[]>({
key: 'todos',
default: [
{
id: uuid(),
title: '๋ฆฌ์กํธ ๊ณต๋ถ',
content: '๋ฆฌ์กํธ ์๋ จ๊ฐ์ ์ฒ์๋ถํฐ ๋ณต์ตํ๊ธฐ',
isDone: false,
},
...
],
});
์ ์ฉ
Todo ์ถ๊ฐ
useState๋ฅผ ์ฐ๋ฏ์ด useRecoilState()
ํ
์ผ๋ก ์์ ๋ง๋ state๋ฅผ ๊ฐ์ ธ์จ๋ค.
const [todos, setTodos] = useRecoilState<TodoType[]>(todoState);
...
const submitHandler = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
...
const newTodo: TodoType = {
id: uuid(),
title,
content,
isDone: false,
};
setTodos([...todos, newTodo]); // setTodos๋ก ์ ์ญ์ํ์ ์ถ๊ฐํด์ฃผ๊ธฐ
setTitle('');
setContent('');
return true;
};
Todo ์๋ฃ ํ ๊ธ, ์ญ์
๊ธฐ์กด ๋ฆฌ๋์์ reducers ์์์ ์ด๋ฃจ์ด์ง๋ ๋ก์ง์ด ํธ๋ค๋ฌ ํจ์ ์์์ ์ด๋ฃจ์ด์ง๋ค๊ณ ๋ณด๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
const [todos, setTodos] = useRecoilState<TodoType[]>(todoState);
// ํฌ๋ ์๋ฃ/์ทจ์ ํ ๊ธ ํธ๋ค๋ฌ
const toggleDoneHandler = (id: string) => {
const newState = todos.map((item) => {
return item.id === id
? {
...item,
isDone: !item.isDone,
}
: item;
});
setTodos(newState);
};
// ํฌ๋ ์ญ์ ํธ๋ค๋ฌ
const deleteTodoHandler = (id: string) => {
if (window.confirm('ํด๋น ํฌ๋๋ฅผ ์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น?')) {
const newTodos = todos.filter((todo) => todo.id !== id);
setTodos(newTodos);
}
};
Todo ์์ธ
state์ ๊ฐ๋ง ํ์ํ ๊ฒฝ์ฐ, useRecoilValue()
ํ
์ผ๋ก setterํจ์ ์์ด state๊ฐ๋ง ๊ฐ์ ธ์ฌ ์ ์๋ค.
const Detail = () => {
const todos = useRecoilValue<TodoType[]>(todoState);
const param = useParams();
// id์ ์ผ์นํ๋ ํฌ๋ ์ฐพ๊ธฐ
const todo = todos.find((item) => item?.id === param?.id);
Todo ์์
todo ์์ ๋ ์์ ๋น์ทํ๊ฒ ๋ฆฌ๋์์ ์์ฑํ๋ ๋ก์ง์ ๊ฐ์ ธ์์ ์ฝ๊ฒ ์์ ํ ์ ์๋ค.
const [todos, setTodos] = useRecoilState<TodoType[]>(todoState);
...
const editTodoHandler = (id: string) => {
...
const newState = todos.map((item) => {
return item.id === id
? {
...item,
title: newTitle,
content: newContent,
}
: item;
});
setTodos(newState);
}
setIsEdit(!isEdit);
};
์ด๋ฏธ์ง๊ฐ ์์์ก์ง๋ง.. ์๋ฌดํผ ๋ฆฌํฉํ ๋ง ์๋ฃ!...
ํ์คํ ๋ฆฌ๋์ค์ ๋นํด ๊ฐ๋ณ๊ณ ์ฝ๊ฒ ์ ์ฉํ ์ ์๋ ๊ฒ ๊ฐ๋ค.
'๐ Studying > ๐ TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Emotion vs SCSS vs Styled-components (0) | 2023.02.06 |
---|---|
[TypeScript] CRA์์ tsconfig ์ ๋๊ฒฝ๋ก ์ง์ ํ๊ธฐ (0) | 2023.02.03 |
[Next.js] Next.js์ SSG, ISR (0) | 2023.02.01 |
[Next.js] Next.js ๊ธฐ๋ณธ ๊ฐ๋ (0) | 2023.01.31 |
[TypeScript] ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ (0) | 2023.01.27 |
Comment