useState 훅 세터가 상태를 잘못 덮어씁니다.
문제는 다음과 같습니다.버튼 클릭 한 번으로 두 가지 기능을 호출하려고 합니다.두 함수 모두 상태를 업데이트합니다(useState 훅 사용 중).첫 번째 함수는 값 1을 'new 1'로 올바르게 업데이트하지만, 1s(setTimeout) 후 두 번째 함수가 실행되어 값 2가 'new 2'로 변경됩니다.값 1을 다시 '1'로 설정합니다.왜 이런 일이 생기는 건가요?잘 부탁드립니다!
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState({ ...state, value1: "new 1" });
};
const changeValue2 = () => {
setState({ ...state, value2: "new 2" });
};
return (
<>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</>
);
};
export default Test;
폐쇄지옥에 온 걸 환영해이 문제가 발생하는 이유는setState
라고 불리고 있습니다.state
새로운 메모리 참조를 취득하지만, 그 기능은changeValue1
그리고.changeValue2
, 클로징을 위해 이전 이니셜을 유지합니다.state
언급.
이 솔루션을 통해setState
부터changeValue1
그리고.changeValue2
는 콜백을 사용하여 최신 상태를 가져옵니다(이전 상태를 파라미터로 함).
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState((prevState) => ({ ...prevState, value1: "new 1" }));
};
const changeValue2 = () => {
setState((prevState) => ({ ...prevState, value2: "new 2" }));
};
// ...
};
이 폐쇄 문제에 대한 폭넓은 논의를 이곳저곳에서 볼 수 있습니다.
기능은 다음과 같습니다.
const changeValue1 = () => {
setState((prevState) => ({ ...prevState, value1: "new 1" }));
};
const changeValue2 = () => {
setState((prevState) => ({ ...prevState, value2: "new 2" }));
};
따라서 액션이 실행될 때 이전 상태를 사용하여 현재 상태의 기존 속성이 누락되지 않았는지 확인합니다.따라서 폐쇄를 관리할 필요가 없습니다.
언제changeValue2
기동되어 초기 상태가 유지되어 상태가 초기 상태로 되돌아가고 나서value2
속성이 작성되었습니다.
다음에changeValue2
그 후에 호출되어 상태를 유지합니다.{value1: "1", value2: "new 2"}
,그렇게value1
속성을 덮어씁니다.
이 경우 화살표 기능이 필요합니다.setState
파라미터를 지정합니다.
const Test = () => {
const [state, setState] = React.useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState(prev => ({ ...prev, value1: "new 1" }));
};
const changeValue2 = () => {
setState(prev => ({ ...prev, value2: "new 2" }));
};
return (
<React.Fragment>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</React.Fragment>
);
};
ReactDOM.render(<Test />, 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>
지금 일어나고 있는 일은 둘 다changeValue1
그리고.changeValue2
이 두 함수가 처음 렌더링될 때 다음 두 함수가 표시됩니다.
state= {
value1: "1",
value2: "2"
}
버튼을 클릭하면changeValue1
먼저 호출되어 상태가 로 변경됩니다.{value1: "new1", value2: "2"}
역시나
이제 1초 후에changeValue2
이 함수는 아직 초기 상태를 표시합니다({value1; "1", value2: "2"}
이 함수가 상태를 다음과 같이 갱신할 경우:
setState({ ...state, value2: "new 2" });
다음과 같이 표시됩니다.{value1; "1", value2: "new2"}
.
언급URL : https://stackoverflow.com/questions/58193166/usestate-hook-setter-incorrectly-overwrites-state
'programing' 카테고리의 다른 글
Node.js/Express의 모든 요청을 로깅하고 있습니다. (0) | 2023.03.28 |
---|---|
화살표 본문을 둘러싼 예기치 않은 블록 문 (0) | 2023.03.28 |
jQuery Ajax가 iOS에서 작동하지 않음(list.js 포함) (0) | 2023.03.28 |
Oracle (+) 연산자 (0) | 2023.03.28 |
버튼과 같은 반응 구성요소에서 활성, 호버와 같은 복합 반응 인라인 스타일 설정 (0) | 2023.03.28 |