data를 참조해야하기 때문에 App.js안에서만 상태관리가 이루어질 수 밖에 없다.
현재 app.js 코드가 길어서 넘 무거움..!!
목표: 상태변화 로직들을 컴포넌트에서 분리하여 좀 더 가볍게 만들기.
const [<상태 객체>, <dispatch 함수>] = useReducer(<reducer 함수>, <초기 상태>, <초기 함수>)
reducer 함수는 현재 state 객체,action 객체를 인자로 받아서 새로운 state를 리턴하는 함수이다.
행동객체는 reducer에서 어떤 행동을 할지 알려주는 type과, 그외에 필요한 데이터가 있으면 담을 수 있다.
dispatch가 필요한 데이터들을 싣고 reducer 상태 창고까지 가면, 거기서 가공을 해서 새로운 state를 배송하는 그런 느낌이다 ㅎㅎ dispatch가 버스같은 느낌~~
const [data,dispatch] = useReducer(reducer,[]);
useState대신 useReducer를 넣어주었고, 초기값은 역시 빈배열이다!
처음에 getData() 함수에서 얻어낸 initData를 data 로 설정해주어야한다.
dispatch({type:'INIT',data:initData})
getData 함수 안에 dispatch 버스를 initData를 태워서 보내주면 된다~🚙
case 'INIT' :{
return action.data;
}
그러면 이제 data라는 상태는 initData로 변경이 된 것이다.
const reducer=(state,action)=>{
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;
}
}
onCreate,onRemove,onEdit도 마찬가지로 type.action을 지정해 주어서 원하는 행동을 넣으면 된다.