Zustand Library Document - dev-team-projects/DeliTalk GitHub Wiki
์์ฑ์ : ์์ฑ์ค, ์ ํ์, ์ด์ค์
Zustand๋ฅผ ๋ค์ด๊ฐ๊ธฐ ์ ์..
export const INIT_CHARACTER = 'INIT_CHARACTER';
export const MAIN_CHARACTER = 'MAIN_CHARACTER';
export const MAIN_CHARACTER_DEPT = 'MAIN_CHARACTER_DEPT';
// Action Creator ํจ์
export const initChar = () => ({
type: INIT_CHARACTER,
});
export const mainChar = (newPosition) => ({
type: MAIN_CHARACTER,
payload: newPosition,
});
export const mainCharDept = (newPosition) => ({
type: MAIN_CHARACTER_DEPT,
payload: newPosition,
});
- type์ ์ง์ ๋ ํ์ ์์ฑ์ด์ง๋ง payload๋ ์ง์ ๋ ์์ฑ์ด ์๋๋๋ค.(๊ดํ)
import {
INIT_CHARACTER,
MAIN_CHARACTER,
MAIN_CHARACTER_DEPT,
} from '../actions/actions';
const initialState = {
name: '',
currentPosition: [280, 0, -355],
deptInitPosition: [0, 0, 0],
};
export function mainCharReducer(state = initialState, action) {
switch (action.type) {
case INIT_CHARACTER:
return {
...state,
name: '',
currentPosition: [280, 0, -355],
deptInitPosition: [0, 0, 0],
};
case MAIN_CHARACTER:
// console.log('action.payload', action.payload)
return {
...state,
name: 'SJ',
currentPosition: action.payload,
deptInitPosition: state.deptInitPosition,
};
case MAIN_CHARACTER_DEPT:
return {
...state,
name: 'SJ',
currentPosition: state.currentPosition,
deptInitPosition: action.payload,
};
default:
return state;
}
}
import { createStore } from 'redux';
import rootReducer from '../reducers/rootReducer';
// ์คํ ์ด ์ ์
const store = createStore(rootReducer);
export default store;
import { combineReducers } from 'redux';
import { mainCharReducer } from './mainCharReducer';
// ...
// ๋ชจ๋ ๋ฆฌ๋์ ๊ฒฐํฉ - ์ฑ์ค
const rootReducer = combineReducers({
mChar: mainCharReducer,
// ...
});
export default rootReducer;
<Provider store={store}>
<BrowserRouter>{/* ... */}</BrowserRouter>
</Provider>
const myChar = useSelector((state) => state.mChar);
//...
useEffect(() => {
dispatch(mainChar(targetPosition));
}, [targetPosition]);
import { atom } from 'recoil';
export const isStartScene = atom({
key: 'isStart',
default: false,
});
// ...
const setStart = useSetRecoilState(isStartScene);
//...
return (
<motion.group
onAnimationComplete={() => setStart(true)}
{/* ... */}
>
<Text3D
{...fontStyle}
>
Hello Seong Jun
<meshNormalMaterial />
</Text3D>
{/* ... */}
</motion.group>;
)
// ...
const isStart = useRecoilValue(isStartScene)
return (
{isStart && <Car />}
// ...
)
// ...
// ์ด๊ธฐ ์ํ
const initialState = {
keyword: '',
checkIn: formatDate(checkInDate),
checkOut: formatDate(checkOutDate),
tripDay: 1,
numberOfPeople: 2,
};
export const useAccomSearchStore = create(
persist(
(set, get) => ({
initialState,
setKeywordState: (value) => set({ keyword: value }),
setCheckInState: (date) => set({ checkIn: date }),
setCheckOutState: (date) => set({ checkOut: date }),
setTripDayState: (day) => set({ tripDay: day }),
setNumberOfPeople: (count) =>
set({ numberOfPeople: count === 1 ? 2 : count }),
resetState: () => set(initialState),
}),
{
name: 'accomSearchStore',
getStorage: () => localStorage,
partialize: (state) => ({
keyword: state.keyword,
checkIn: state.checkIn,
checkOut: state.checkOut,
tripDay: state.tripDay,
numberOfPeople: state.numberOfPeople,
}),
}
)
);
const state = useAccomSearchStore((state) => state);
// or
const { checkIn, checkOut, tripDay } = useAccomSearchStore((state) => state);
const { setCheckInState, setCheckOutState, setTripDayState, resetState } =
useAccomSearchStore((state) => state);
์ฌ๋ฌ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋น๊ตํด๋ดค์ ๋ Zustand๊ฐ ํจ์ฌ ๋จ์ํฉ๋๋ค.
- ๊ฐ๋ ฅํ์ง๋ง ๋ณด์ผ๋ฌํ๋ ์ดํธ๊ฐ ๋ง์ต๋๋ค.
- ์ค์ ์ด ๋ณต์กํด ์ด๋ฐ ์ง์ ์ฅ๋ฒฝ์ด ๋์ต๋๋ค.
- Recoil์ React ์ ์ฉ์ด๊ณ ์ํฐ ๊ธฐ๋ฐ์ ๊ด๋ฆฌ ๋ฐฉ์์ด ์ง๊ด์ ์
๋๋ค.
-
useRecoilState
,useRecoilValue
๊ฐ์ ํ ์ ํตํด atom์ ์ง์ ๊ฐ์ ธ์ค๊ณ ์ ๋ฐ์ดํธํฉ๋๋ค. - props drilling์ด ํ์ ์๊ณ , API ์ฌ์ฉ ๋ฐฉ์์ด React์ useState์ ๊ฑฐ์ ์ ์ฌํฉ๋๋ค.
const [text, setText] = useRecoilState(textState);
-
- ๊ณต์์ ์ผ๋ก Recoil์ SSR์ ์ง์ํ์ง ์์ต๋๋ค.
- Recoil์ ๊ธฐ๋ณธ์ ์ผ๋ก CSR์ ๋๋ค.
- ์ปค๋ฎค๋ํฐ ๊ท๋ชจ๊ฐ ์์ง ์๋ค๊ณ ํ๋จํ์ต๋๋ค.
ํ์ง๋ง React + Spring Boot ์กฐํฉ์ผ ๊ฒฝ์ฐ CSR ๋ฐฉ์์ด๋ฏ๋ก Recoil์ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
-
Redux์ ํต์ฌ ๊ธฐ๋ฅ์ ํจ์ฌ ๋จ์ํ๊ฒ ๊ตฌํํฉ๋๋ค.
- ์ฝ๋๋์ด ์ ๊ณ ์ค์ ์ด ๊ฐํธํฉ๋๋ค.
-
๋ฆฌ๋ ๋๋ง ์ต์ ํ, ๋น๋๊ธฐ ์ง์, ๋ก์ปฌ์คํ ๋ฆฌ์ง ์ฐ๋, ๋ฏธ๋ค์จ์ด ํ์ฅ ๋ฑ ์ค๋ฌด์์ ํ์ํ ๊ธฐ๋ฅ๋ค์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
-
useStore ํ ์ ํตํด ํ์ํ ์ํ๋ง ๊ตฌ๋ ํ๋ ๊ตฌ์กฐ๊ฐ ์ฑ๋ฅ ๋ฉด์์๋ ํจ์จ์ ์ ๋๋ค.
ํ์ฅ์ฑ๊ณผ ์์ฐ์ฑ์ ๋ชจ๋ ๊ณ ๋ คํ ๊ฒฝ์ฐ Zustand๊ฐ ๋ ๋ซ์ต๋๋ค.
- ํ ๋ง ์ค์
- ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ๋ณด
- ๋ชจ๋ฌ ์ํ
๋ฑ๋ฑ..
-
Zustand์ ๊ฐ์ฅ ํฐ ๋งค๋ ฅ์ ๋จ์ํ API์ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ค์ด๋ ์ฑ๋ฅ ์ต์ ํ์ ์์ต๋๋ค.
- ๋จ์ํ API
์ ์ญ ์ํ๋ฅผ ๋งค์ฐ ๊ฐ๋จํ๊ฒ ์ ์ธํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๋ณ๋์ Provider๋ ๋ณต์กํ boilerplate ์ฝ๋๊ฐ ํ์ ์์ต๋๋ค.
- ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง ์ต์ํ
์ ํ์ ๊ตฌ๋ (Selector)์ ํตํด ํ์ํ ์ํ๋ง ๊ตฌ๋ ํ ์ ์๊ณ , ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๊ด๋ จ๋ ์ปดํฌ๋ํธ๋ง ๋ฆฌ๋ ๋๋ง ๋ฉ๋๋ค.
- ๋จ์ํ API
-
Redux๋ ์ํ๋ฅผ ๋ง๋ค๊ธฐ ์ํด action, reducer, dispatch๋ฅผ ์ ์ํ๊ณ ์ฐ๊ฒฐํด์ผ ํ๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ๋ง์ง๋ง, Zustand๋ ๋จ์ง ํ๋์ create ํจ์๋ก ์ํ์ ๋ก์ง์ ๋ชจ๋ ์ ์ํ ์ ์์ด์ ์ฝ๋๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํฉ๋๋ค.
-
๊ทธ๋ฆฌ๊ณ ์ฑ๋ฅ ๋ฉด์์๋, Redux๋ Context API๋ ์ํ๊ฐ ๋ฐ๋๋ฉด ํด๋น ์ํ๋ฅผ ์ฐธ์กฐํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋ ๋ฐ๋ฉด, Zustand๋ useStore(selector)๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ํ ์ํ๋ง ๊ตฌ๋ ํ๊ณ ๊ทธ ์ธ ์ปดํฌ๋ํธ๋ ๋ฆฌ๋ ๋๋ง๋์ง ์์ ๋ถํ์ํ ๋ ๋๋ง์ ์ค์ผ ์ ์์ต๋๋ค.