* reducer - state update하는 역활 (은행)
* dispath - state 업데이트를 위한 요구
* action - 요구 내용
* reducer - state update하는 역활 (은행)
* dispath - state 업데이트를 위한 요구
* action - 요구 내용
const reducer = {state, acticn} => {};
const [money, dispatch] = useReducer(reducer,0)
//reducer 에서 money 는 state 이고 dispathch로 내보낸다.
// useReducer(reducer,0) 에서 reducer 는 실행할 함수이고 , 0은
// money 의 초기값이다.
// 위의 reducer 함수는 2갱의 props를 받는데 state는 money의 상태이고
// action 은 실행할 명령어이다.
// money 는 오직 reducer 에서만 작동되고 money를 변화시키려면
// dispatch 를 이용해야한다. 즉 dispatch 안에 action을 넣는다.
reducer 함수를 움직이기 위해 버튼 명령에 dispatch 를 두었더니 콘솔창에
'reducer 가 일을 합니다!' 라고 나왔다.
const reducer = (state, action) =>{
console.log('reducer 가 일을 합니다!',state,action);
}
//console 에 state,action 을 넣었다. 그리고 콘솔창을 보니
// 0, undefined 가 나왔다. 0은 money의 state 갑싱고 undefined 는
// 버튼에서 dispathch() 값이 없기에 undifined 가 나온것이다.
dispathch 애는 객체로서 type 에는 하려는 것의 이름과 payload 에는 넘길 값을 정한다.
ex) dispatch ({ type: 'deposit', payload: number });
const reducer = (state, action) =>{
console.log('reducer 가 일을 합니다!',state,action);
return state + action.payload;
}
// reducer의 return 된 값을 보면 state 는 money 의 초기값이라 0이고
// action.payload 값은 위의 payload 값이 3000 이다. 따라서
// return 0 + 3000 이라 return return 값은 3000 이다.
const reducer = (state, action) =>{
console.log('reducer 가 일을 합니다!',state,action);
return state + action.payload;
}
reducer 에는 type 에 따라 여러 가지 기증을 할수 있다. 0
switch(action.type) {
case 'deposit':
return state + action.payload;
default :
return state;
}
switch(action.type) {
case 'deposit':
return state + action.payload;
case 'withdraw':
return state - action.payload;
default :
return state;
}
<button onClick={()=>{
dispatch({ type: 'withdraw', payload: numner})
}}>
*출금!
이번에는 변수들 모아서 한번에 제어하려는 법이다.
const ACTION_TYPES = {
deposit: 'deposit',
withdraw : 'withdraw',
}
switch(action.type) {
case ACTION_TYPES.deposit:
return state + action.payload;
case ACTION_TYPES withdraw:
return state - action.payload;
default :
return state;
}
* Warning: Each child in a list should have a unique "key" prop.
이것은 각 자식 요소들은 key 값을 가져야 한다고 했기 때문에 key 값도 props 로 넣어 둔다.
이제 이름을 입력해 보자! 이름을 입력해서 학생 수를 높이기 위해서는 studentsInfo를 움직여야 하므로 reducer를 변화시켜야 한다.
<button onCliack={()=>{
dispatch({type: 'add-student', payload: {name}})
}}>추가</button>
const reducer = (state, action) =>{
switch(action.type):
const name = action.payload.name;
const newStudent = {
id: Date.now(),
name: name, // 객체 이름이 서로 같을 경우 하나로 쓸수 있다.
isHere:false,
};
return {
count = state.count +1,
students = [...state.students, newStudent],
};
}
* student name 지우기
지우는 버튼은 Student 컴포턴트에 있어서 지울 수 있는 명령인 action 값을 움직일 수 있게 하기 위해
Student 컴포넌트에 dispatch 값을 넘겨 준다. id 값을 넘겨주는 것은 delete 할 이름을 선택 할 수
있게 하기 위해서이다.
case 'delete-student':
return {
count : state.count -1,
students: state.students.filter(student =>
student.id !== action.payload.id),
}
students: state.students.filter(student => student.id !== action.payload.id)
이것은 filter 기능으로 student.id 와 action.payload.id 값이 같지 않은 부분을 가지고 같은 부분을 걸러내는 방식이다.
* 학생의 출석부 기능
<Student key={student.id}
name={student.name} dispathc={dispatch} id={student.id} isHere={student.isHere} />
<span
style={{
textDecoration: isHere ? 'line-through':'none',
color : isHere ? 'gray':'black',
}}
onClick={()=>{
dispatch({type:'mark-student',payload:{id}})
}}
>
학생들의 출석을 하면 줄을 긋고 안하면 줄을 지운다. 그리고 색도 바뀐다. 이 모든 것을 span tag의 style 에서 한다.
App()
case 'mark-student':
return{
count: state.count,
student: state.students.map((student)=>{
if(student.id === action.payload.id){
return {...student, isHere: !student.isHere}
}
return student
})
}