useState 대신 useReducer를 사용하면 복잡한 상태관리를 용이하게 처리 할 수 있다.
data는 상태값을 의미하고 dispatch는 동기화시키는 메소드이다.
const [data,dispatch] = useReducer(reducer,[]);
인터페이스를 통해 타입 분리
interface init{
type:"INIT"
data:Info[]
}
interface create{
type:"CREATE"
data:Info
}
interface remove{
type:"REMOVE"
targetId:number
}
interface edit{
type:"EDIT"
targetId:number,
newContent:string
}
reducer 메서드는 dispath메서드의 스위치들이라고 보면 된다.
const reducer = (state:Info[],action:init | create|remove|edit)=>{
switch (action.type) {
case 'INIT':{
return action.data;
}
case 'CREATE':{
const created_date = new Date().getTime();
const newItem = {...action.data,created_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;
}
}
state는 최신화된 data라고 봐도 무방하다.return을 하게되면 data를 동기화 한다.
const onCreate:oncreate = useCallback((autor:string,content:string,emotion:number)=>{
const createDate = new Date().getTime();
const newItem = {
autor,
content,
emotion,
createDate,
id:dataId.current,
};
dataId.current+=1;
dispatch({type:'CREATE',data:{autor,content,emotion,createDate,id:dataId.current}})
},[]);
const onDelete:ondelete = useCallback((targetId)=>{
dispatch({type:"REMOVE",targetId})
},[]);
const onEdit:onedit = useCallback((targetId,newContent)=>{
dispatch({type:"EDIT",targetId,newContent});
},[]);