const [state, dispatch] = useReducer(reducer, initialArg, init?)
useState를 사용했던 부분을 useReducer로 바꿔줄 것이다!
왜? 복잡한 상태변화 로직들을 컴포넌트 밖에다가 분리해놓기 위해서 😀
예시)
const initialState = 0;
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
};
const [count, dispatch] = useReducer(reducer, initialState);
실전)
//App.js
🤖 App밖에 reducer 정의
reducer가 return 하는 값이 새로운 상태(데이터)의 값이 됨
const reducer=(state,action)=>{
switch (action.type){
case 'INIT' : {
return action.data
}
case 'CREATE' : {
const create_date = new Date().getDate();
const newItem ={
...action.data, //create_date 외의 항목들
create_date
}
return[newItem, ...state];
}
case 'REMOVE' : {
return state.filter((it)=>it.id !== action.targetId);
}
case 'EDIT' : {
return state.map((it)=>it.id === action.targetId ?
{...it, content:action.newContent} : it
)
}
default :
return state;
}
}
function App() {
✏️ 변경 전
const [data, setData] = useState([]);
✏️ 변경 후
const [data, dispatch] = useReducer(reducer,[]);
🤖 1.initData를 INIT으로
const initData = res.slice(0,20).map((it)=>{
.
.
.
✏️ 변경 전
setData(initData);
✏️ 변경 후
dispatch({type: "INIT",data:initData});
})
🤖 2.onCreate를 CREATE으로
const onCreate = useCallback((author,content,emotion) => {
.
.
.
✏️ 변경 전
setData(initData);
✏️ 변경 후
(항목이 생성된 후 아이디값은 +1을 해주어야하기 때문에 dispatch 구문은 상위에 작성해야함)
dispatch({
type:'CREATE',
data:{author, content, emotion, id: dataId.current},
})
})
🤖 3.onRemove를 REMOVE으로
const onRemove = useCallback((targetId) => {
.
.
.
✏️ 변경 전
setData(data.filter((it)=> it.id !==targetId));
✏️ 변경 후
dispatch({type: "REMOVE", targetId})
})
🤖 4.onEdit EDIT으로
const onEdit = useCallback((targetId, newContent) => {
.
.
.
✏️ 변경 전
setData((data) =>
data.map((it) =>
it.id === targetId ? { ...it, content: newContent } : it
)
);
✏️ 변경 후
dispatch({type: "EDIT", targetId,newContent})
})
}
강의 두번째 들으니까 드디어 이해가 가기 시작한다..야호