๐์ค๋ ๋ฐฐ์ด ๊ฒ
recoil
- Atom: ๋ฐ์ดํฐ ์ํ์ ๋จ์, atom์ ์ด๋ค ์ปดํฌ๋ํธ์์๋ ์ฝ๊ณ ์ธ ์ ์์ผ๋ฉฐ atom ๊ฐ์ ์ฝ๋ ์ปดํฌ๋ํธ๋ค์ ์๋ฌต์ ์ผ๋ก atom์ ๊ตฌ๋ ํ๋ค. ๋ฐ๋ผ์ atom์ ๋ณํ๊ฐ ์์ผ๋ฉด ๊ตฌ๋ ํ๊ณ ์๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ ๋ ๋๋ง๋๋ค.
- Selector: atom์์ state๋ฅผ ๊ฐ์ ธ์จ ํ ์๋ก์ด state๋ฅผ ๋ง๋ค์ด์ ๋ฐํ -> ํ์ฌ state๋ฅผ ๊ฐ์ง๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๋ ๋ฐ ์ฃผ๋ก ์ฌ์ฉํ๋ ๊ฒ ๊ฐ๋ค. ex) todo ๋ฆฌ์คํธ ํํฐ๋ง, todo ๋ฆฌ์คํธ ํต๊ณ ...
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
get: get ์ธ์๋ฅผ ํตํด atoms์ ๋ค๋ฅธ selectors์ ์ ๊ทผํ ์ ์๋ค. ๋ค๋ฅธ atoms๋ selectors์ ์ ๊ทผํ๋ฉด ์๋์ผ๋ก ์ข ์ ๊ด๊ณ๊ฐ ์์ฑ -> ์ฐธ์กฐํ๋ ๋ค๋ฅธ atoms๋ selector๊ฐ ์ ๋ฐ์ดํธ๋๋ฉด ์ด ํจ์๋ ๋ค์ ์คํ๋๋ค.
- get ํจ์๋ง ์ ๊ณต๋ ๊ฒฝ์ฐ
: ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํ RecoilValueReadonly ๊ฐ์ฒด ๋ฐํ
- set ํจ์๋ ์ ๊ณต๋ ๊ฒฝ์ฐ
:์ฐ๊ธฐ ๊ฐ๋ฅํ RecoilState ๊ฐ์ฒด ๋ฐํ
- useRecoilState(): ์ํ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์์ ํ ์ ์๋ค.
- useRecoilValue(): ์ํ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ค. read only
- useSetRecoilState(): ์ํ๊ฐ์ ์์ ํ ์๋ง ์๋ค. write only
- useResetRecoilState(): ์ํ๊ฐ์ ์ด๊ธฐ๊ฐ์ผ๋ก ๋ฆฌ์ ํ๋ค.
recoil ๋น๋๊ธฐ ํต์
- atom๊ณผ selector๋ก ๋๊ธฐ์ ํต์ ํ๊ธฐ
const currentUserIDState = atom({
key: 'CurrentUserID',
default: 1,
});
const currentUserNameState = selector({
key: 'CurrentUserName',
get: ({get}) => {
return tableOfUsers[get(currentUserIDState)].name;
},
});
function CurrentUserInfo() {
const userName = useRecoilValue(currentUserNameState);
return <div>{userName}</div>;
}
function MyApp() {
return (
<RecoilRoot>
<CurrentUserInfo />
</RecoilRoot>
);
}
๋ง์ฝ user์ ์ด๋ฆ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋์ด ์๋ค๋ฉด promise๋ฅผ ๋ฆฌํดํ๊ฑฐ๋ async ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ๋ง ํด๋ ๋๋ค.
const currentUserNameQuery = selector({
key: 'CurrentUserName',
get: async ({get}) => {
const response = await myDBQuery({
userID: get(currentUserIDState),
});
return response.name;
},
});
function CurrentUserInfo() {
const userName = useRecoilValue(currentUserNameQuery);
return <div>{userName}</div>;
}
propmise๊ฐ resolve๋๊ธฐ ์ ์๋ ๋ฌด์์ ๋ ๋ํ ์ ์์๊ฐ?
-> React Suspense๋ฅผ ์ด์ฉํด์ ๋์ฒด ui๋ฅผ ๋ ๋ํ ์ ์๋ค.
function MyApp() {
return (
<RecoilRoot>
<React.Suspense fallback={<div>Loading...</div>}>
<CurrentUserInfo />
</React.Suspense>
</RecoilRoot>
);
}
๋ง์ฝ Suspense๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ์๋ useRecoilValueLoadable() ํ ์ ์ฌ์ฉํด์ ๋ ๋๋ง ์ค ์ํ๋ฅผ ํ์ธํ ์ ์๋ค.
function UserInfo({userID}) {
const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
switch (userNameLoadable.state) {
case 'hasValue':
return <div>{userNameLoadable.contents}</div>;
case 'loading':
return <div>Loading...</div>;
case 'hasError':
throw userNameLoadable.contents;
}
}
์๋ฌ๋ ErrorBoundary๋ฅผ ์ด์ฉํด์ ์ก์ ์ ์๋ค.
function MyApp() {
return (
<RecoilRoot>
<ErrorBoundary>
<React.Suspense fallback={<div>Loading...</div>}>
<CurrentUserInfo />
</React.Suspense>
</ErrorBoundary>
</RecoilRoot>
);
๐ญ๋ฐฐ์ด ์
ํ ํ๋ก์ ํธ์ ๋ฆฌ์ฝ์ผ์ ์ฌ์ฉํ๊ธฐ๋ก ํด์ ๋ฆฌ์ฝ์ผ์ ๋ํ ๊ณต๋ถ๋ฅผ ์ฒ์ ์์ํ๋ค. ์ํ๊ด๋ฆฌ๋ฅผ ์ ๋๋ก ์ฌ์ฉํด๋ณธ ์ ์ด ์์ด์ ์์ง ๊ฑฑ์ ์ด ๋ง์๋ค. ์ด์ ์๋ context API๋ง ์ฌ์ฉํด๋ดค๋๋ฐ ๋ฆฌ์ฝ์ผ ๊ณต์๋ฌธ์๋ฅผ ์ฝ์ด๋ณด๋ ๊ธฐ์กด ๋ฆฌ์กํธ ํ ์ฌ์ฉ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์์์ ๋ณด๋ค ์ฝ๊ฒ ๋ฐฐ์ธ ์ ์์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์๋ค. ๋ฐ๋ธ์ฝ์ค ๊ฐ์์์ ๋ฆฌ๋์ค๋ฅผ ๊ฐ๋จํ๊ฒ ๊ฒฝํํด๋ณธ ์ ์ด ์์๋๋ฐ ์ ๋ง ์ด๋ ต๊ณ ์ดํด๊ฐ ์๋๋ ๊ธฐ์ต์ด ์์ด์ ๋ ๊ฑฑ์ ํ์๋ค. ๊ทธ๋ฐ๋ฐ ์ค์ ๋ก ๋ด๋ณด๋ ๋ฆฌ๋์ค๋ณด๋ค ๋ ๊ฐ๋จํ๊ณ ์ฌ์ฉ๋ฐฉ๋ฒ๋ ๋ณต์กํ์ง ์์ ๊ฒ ๊ฐ๋ค. selector๋ฅผ ํจ์จ์ ์ผ๋ก ์ฐ๋ ค๋ฉด ๋ฆฌ์ฝ์ผ์ ์ต์ํด์ ธ์ผ๊ฒ ๋ค๋ผ๋ ์๊ฐ์ด ๋ค์์ง๋ง ์ด๊ฑด ๊ณต๋ถํ๊ณ ํ๋ก์ ํธ ์งํํ๋ฉด์ ์ต์ํด์ ธ์ผ ํ ๊ฒ ๊ฐ๋ค.
๋ฆฌ์ฝ์ผ์ ๋ฅ์ํด์ง๋ฉด ๋์ค์ ๋ฆฌ๋์ค๋ ๋ค์ ์ ๋๋ก ๋ฐฐ์๋ณด๊ณ ์ถ๋ค. ๊ทธ๋ฌ๋ฉด ๋ฆฌ์ฝ์ผ์ด ์ผ๋ง๋ ๊ฐํธํ์ง ๋ ์ฒด๊ฐ๋ ๊ฒ ๊ฐ๋ค.
'์ผ์ > Today I Learned' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
2023.03.29 [๊ฒ์ ์๊ณ ๋ฆฌ์ฆ, ๋ฒ๋ธ ์ ๋ ฌ] (0) | 2023.03.29 |
---|---|
2023.02.08 (0) | 2023.02.08 |
2023.02.06 (0) | 2023.02.07 |
2023.02.03 (0) | 2023.02.03 |
2023.02.01 (0) | 2023.02.01 |