prone to: ~의 경향이 있는
spot: 발견하다, 알아채다
entity: 독립체
abstract: 추상적인
redundancy: 불피요한 중복
far off: 아득한 저편, 크게 벗어난, 아주 잘못된
state끼리 상호작용이 많을 때
useState()를 사용하면 코드가 복잡해져서 버그가 나타나기 쉬움
더 강력한 상태관리가 필요할 때 useReducer()을 사용해서 useState()를 대체할 수 있음
setFormIsValid는 두가지 state에 의해 업데이트된다.
setFormIsValid코드가 처리될 때 비동기로 처리되기 된다. 즉 이벤트 핸들러 안에서 누적하여 처리하지 않고 마지막에 요청되는 변경 사항이 오버라이딩된다. 그래서 마지막 변경 사항이 정확하게 반영되지 않을 수 있다. 이를 해결하기 위해 화살표 함수를 넣어주는데
setFormIsValid의 form의 유효성 state의 마지막snapshot에 따른 업데이트가 아닌
두가지의 다른 state에 의해 업데이트가 되야하기 때문에 화살표 함수를 써서 해결할 수 없다.
이를 해결하기 위해 useReducer()을 사용한다. 즉 다음과 같은 상황에 useReducer()를 써주면 좋다.
연관된 2개의 state를 묶어줄 수 있고
state update가 다른 state에 의존할 때
const [state, dispatchFn] = useReducer(reducerFn, initialState, initFn)
useReducer는 2개의 값을 받아서 배열로 반환
function reducer(state, action){
//새로운 상태를 만드는 로직
const nextState=...
return nextState
}
컴포넌트가 반환하는 상태는 곧 컴포넌트가 지닐 새로운 상태.
action: 업데이트 위한 정보, 주로 type을 지닌 객체로 사용
initialState: 초기 상태
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
function Counter() {
const [number, dispatch] = useReducer(reducer, 0);
const onIncrease = () => {
dispatch({ type: 'INCREMENT' });
};
const onDecrease = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
컴포넌트 밖에 선언
reducer function 안에 컴포넌트 안에 있는 데이터 필요 없음 그래서 reducer function은 컴포넌트 스코프 밖에서 만들 수 있음