useReducer에서 스프레드 연산자를 무시하면 어떤 경우에 버그가 발생합니까?
useReducer
내가 본 대부분의 예에서 스프레드 연산자는 상태를 보존하는 데 사용되었습니다. 그러나 내 모든 관행에서 그것을 무시해도 문제가 발생하지 않았습니다. 감속기는 스프레드 연산자 없이도 상태 자체를 보존 할 수있는 것 같습니다. 다음 예를 확인하십시오.
const initialState = {
color: 'black',
bgColor: 'white'
}
const reducer = (state, action) => {
switch (action.type) {
case 'dawn':
return {
...state,
color: 'white',
bgColor: 'purple'
}
case 'reset':
return initialState
default:
return {
state
}
}
}
const UseReducerColorSetter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const { color, bgColor } = state;
return (
<>
<div style={{ color: `${color}`, backgroundColor: `${bgColor}` }} className='card'>
Hello
</div>
<button onClick={() => dispatch({ type: 'dawn' })}>Dawn mode</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</>
)
}
이 예에서 제거해 ...state
도 문제, 상태 변경, 콘솔 오류 등이 발생하지 않습니다.
이 질문에서 나는 물었다 : useReducer에서 스프레드 연산자를 사용해야합니까? 스프레드 연산자를 무시하면에서 문제가 발생 useState
했지만 여전히 useReducer
.
누군가가 문제를 일으키는 스프레드 연산자를 무시하는 몇 가지 예를 제공 할 수 있습니까 useReducer
? 감속기가 상태를 유지할 수 있습니까?
답변
다음은 감속기의 모든 객체 속성을 바꾸지 않으면 손실되는 것을 보여주는 실행 예제입니다. 콘솔에 기록 된 초기 값을 인쇄 된 결과와 비교합니다.
const initialState = {
color: "black",
bgColor: "white"
};
const reducer = (state, action) => {
switch (action.type) {
case "dawn":
return {
bgColor: "purple" // Updated to only return one property to illustrate the problem
};
case "reset":
return initialState;
default:
return {
state
};
}
};
function App() {
const [state, dispatch] = React.useReducer(reducer, initialState);
React.useEffect(() => {
console.log("Initial: ", state)
dispatch({ type: "dawn" });
}, []);
return <div>{JSON.stringify(state)}</div>;
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
감속기 함수 의 시그니처에 주목하십시오 (state, action) => newState
. 이 함수는 새로운 상태를 반환합니다. 따라서 return
감속기에서 가져온 것은 전체적으로 새로운 상태 값입니다. 즉, 루트 상태 개체를 확산하지 않으면 새 개체에 명시 적으로 설정되지 않은 모든 값이 손실됩니다.
질문에 직접 답하기 위해 리듀서 업데이트에서 이전 상태를 전파하지 않으면 상태가 배열 또는 객체 일 때 버그가 발생하고 해당 구조의 모든 값을 수동으로 바꾸지 않습니다.
당신이 경우 항상 각 개체의 속성을 설정하거나 이전 상태를 반환, 당신은 버그가 발생하지 않습니다. 이것은 당신이 질문에 제시 한 시나리오이며 불필요한 것처럼 보이는 이유입니다.
특정 경우에는 상태 값 (color 및 bgColor)을 변경하기 때문에 문제가 발생하지 않거나 영향을 미치지 않습니다. 앱이 항상 bgColor를 가질 것으로 예상하는 경우 문제가 발생할 수 있습니다.
case 'blue':
return {
color: 'blue',
}