Illie

React. useReducer (상태관리) 본문

REACT || REACT NATIVE

React. useReducer (상태관리)

(*ᴗ͈ˬᴗ͈)ꕤ*.゚ 2022. 8. 2. 00:14

개요

상태관리를 위한 것들이 많다

React 자체의 useReducer부터 Redux, Recoil, Jotai 등 뭐를 먼저 배워야할지 모르겠다 생각할 수도 있다

하지만 맥락은 같다

무엇을 먼저 배우던, 그 뒤에 배우는 것에 전이된다

왜냐면 이것들의 존재 이유가 상태관리라는 목적을 달성하기 위함이기 때문이다

 

별코딩이 정말 쉽게 잘 설명했다

상태관리 이해하려고 영상 정말 많이 봤는데 돌고돌아 별코딩에 정착했다

상태관리에 있어선, 별코딩보다 설명잘하는 사람을 못봤다

https://youtu.be/tdORpiegLg0

 

알야야 할 개념 - Reducer, Dispatch, Action

Dispatch(Action) -> Reducer(State, Action) -> State UPDATE!

- reducer: state를 업데이트 하기 위한 역할

- dispatch: state 업데이트를 위한 요구

- action: 요구의 내용

 

코딩 - 기본 세팅

// App.js

const reducer = (state, action) => {};

const initialState = {
  count: 0,
  student: [
    {
      id: date.now(),
      name: 'James',
      isHere: false,
    },
  ],
};

const App = () => {
  const [name, setName] = useState('');
  const [studentInfo, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      <h1>출석부</h1>
      <p>총 학생 수: {studentInfo.count}</p>
      <input
        type="text"
        placeholder="이름을 입력해주세요."
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button>추가</button>
      {studentsInfo.students.map(student => {
        return <Student name={student.name} />;
      })}
    </>
  );
};
// Student.js

const Student = ({ name }) => {
	return (
    <div>
    	<span>{name}</span>
        <button>삭제</button>
    </div>
    )
}
export default Student;

reducer 조작 - add

const reducer = (state, action) => {
	switch(action.type){
    	case 'add-student':
        	const name = action.payload.name;
            const newStudent = {
            	id: Date.now(),
                name,
                isHere: false,
            };
            
            return {
            	count: state.count + 1;
                students: [...state.students, newStudent],
            };
        default:
        	return state;
    }
}

<button onClick={() => {dispatch({type: 'add-student', payload: {name} })}}></button>

reducer 조작 - delete

const student = ({ name, dispatch, id }) => {
	return (
    	<div>
        	<span>{name}</span>
            <button
            	onClick={() => { dispatch({ type: 'delete-student, payload: {id} }) }}
            >삭제</button>
        </div>
    )
}
export default Student;

case 'delete-student':
	return {
    	count: state.count - 1;
        studnets: state.students.filter(
        	student => student.id !== action.payload.id
        )
    };

reducer 조작 - isHere

<span
	style={{
    	textDecoration: isHere ? 'line-through' : 'none',
        color: isHere ? 'gray' : 'black', 
    }}
    onClick={() => {
    	dispatch({ type: 'mark-student', payload: { id } })
    }}
>
	{name}
</span>

case 'mark-student':
	return {
    	count: state.count,
        studnets: state.students.map(student => {
        	if (student.id === action.payload.id) {
            	return {...student, isHere: !student.isHere}
            }
            return student;
        })
    }
Comments