React with Hooks에서 상태를 업데이트하는 올바른 방법은 무엇입니까?
export Example = () => {
const [exampleState, setExampleState] = useState(
{masterField: {
fieldOne: "a",
fieldTwo: {
fieldTwoOne: "b"
fieldTwoTwo: "c"
}
}
})
한 사람이 어떻게 사용하는 것이 setExampleState
업데이 트에 exampleState
에 a
(AN 필드를 추가)?
const a = {
masterField: {
fieldOne: "a",
fieldTwo: {
fieldTwoOne: "b",
fieldTwoTwo: "c"
}
},
masterField2: {
fieldOne: "c",
fieldTwo: {
fieldTwoOne: "d",
fieldTwoTwo: "e"
}
},
}
}
b
(값 변경)?
const b = {masterField: {
fieldOne: "e",
fieldTwo: {
fieldTwoOne: "f"
fieldTwoTwo: "g"
}
}
})
답변
이렇게 새로운 값을 전달할 수 있습니다.
setExampleState({...exampleState, masterField2: {
fieldOne: "c",
fieldTwo: {
fieldTwoOne: "d",
fieldTwoTwo: "e"
}
},
}})
답변
누군가 useState ()를 검색하는 경우 객체에 대한 후크 업데이트
- Through Input
const [state, setState] = useState({ fName: "", lName: "" });
const handleChange = e => {
const { name, value } = e.target;
setState(prevState => ({
...prevState,
[name]: value
}));
};
<input
value={state.fName}
type="text"
onChange={handleChange}
name="fName"
/>
<input
value={state.lName}
type="text"
onChange={handleChange}
name="lName"
/>
***************************
- Through onSubmit or button click
setState(prevState => ({
...prevState,
fName: 'your updated value here'
}));
답변
일반적으로 React 상태에서 깊이 중첩 된 객체를주의해야합니다. 예기치 않은 동작을 방지하려면 상태를 변경없이 업데이트해야합니다. 딥 오브젝트가 있으면 불변성을 위해 딥 클로닝을하게되는데 이는 React에서 상당히 비쌀 수 있습니다. 왜?
상태를 딥 복제하면 React는 변수가 변경되지 않았더라도 변수에 의존하는 모든 것을 다시 계산하고 다시 렌더링합니다!
따라서 문제를 해결하기 전에 먼저 상태를 평평하게 할 수있는 방법을 생각하십시오. 그렇게하면 useReducer ()와 같은 큰 상태를 처리하는 데 도움이되는 멋진 도구를 찾을 수 있습니다.
그것에 대해 생각했지만 여전히 깊게 중첩 된 상태 트리를 사용해야한다고 확신하는 경우 immutable.js 및 Immutability-helper 와 같은 라이브러리에서 useState ()를 사용할 수 있습니다 . 변경 가능성에 대해 걱정할 필요없이 딥 오브젝트를 간단하게 업데이트하거나 복제 할 수 있습니다.
답변
필립 덕분에 도움이되었습니다-제 사용 사례는 입력 필드가 많은 양식을 가지고 있었기 때문에 초기 상태를 객체로 유지하고 객체 상태를 업데이트 할 수 없었습니다. 위의 게시물이 도움이되었습니다 🙂
const [projectGroupDetails, setProjectGroupDetails] = useState({
"projectGroupId": "",
"projectGroup": "DDD",
"project-id": "",
"appd-ui": "",
"appd-node": ""
});
const inputGroupChangeHandler = (event) => {
setProjectGroupDetails((prevState) => ({
...prevState,
[event.target.id]: event.target.value
}));
}
<Input
id="projectGroupId"
labelText="Project Group Id"
value={projectGroupDetails.projectGroupId}
onChange={inputGroupChangeHandler}
/>
답변
파티에 늦었어요 .. 🙂
@aseferov 대답은 전체 개체 구조를 다시 입력하려는 경우 매우 잘 작동합니다. 그러나 목표 / 목표가 Object의 특정 필드 값을 업데이트하는 것이라면 아래 접근 방식이 더 낫다고 생각합니다.
상태:
const [infoData, setInfoData] = useState({
major: {
name: "John Doe",
age: "24",
sex: "M",
},
minor:{
id: 4,
collegeRegion: "south",
}
});
특정 기록을 업데이트하려면 이전 주를 리콜해야합니다. prevState
여기:
setInfoData((prevState) => ({
...prevState,
major: {
...prevState.major,
name: "Tan Long",
}
}));
혹시
setInfoData((prevState) => ({
...prevState,
major: {
...prevState.major,
name: "Tan Long",
},
minor: {
...prevState.minor,
collegeRegion: "northEast"
}));
나는 이것이 비슷한 문제를 해결하려는 모든 사람에게 도움이되기를 바랍니다.
답변
function App() {
const [todos, setTodos] = useState([
{ id: 1, title: "Selectus aut autem", completed: false },
{ id: 2, title: "Luis ut nam facilis et officia qui", completed: false },
{ id: 3, title: "Fugiat veniam minus", completed: false },
{ id: 4, title: "Aet porro tempora", completed: true },
{ id: 5, title: "Laboriosam mollitia et enim quasi", completed: false }
]);
const changeInput = (e) => {todos.map(items => items.id === parseInt(e.target.value) && (items.completed = e.target.checked));
setTodos([...todos], todos);}
return (
<div className="container">
{todos.map(items => {
return (
<div key={items.id}>
<label>
<input type="checkbox"
onChange={changeInput}
value={items.id}
checked={items.completed} /> {items.title}</label>
</div>
)
})}
</div>
);
}
답변
최고의 솔루션은 Immer 라고 생각 합니다. 필드를 직접 수정하는 것처럼 개체를 업데이트 할 수 있습니다 (masterField.fieldOne.fieldx = ‘abc’). 그러나 물론 실제 대상을 변경하지는 않습니다. 초안 개체의 모든 업데이트를 수집하고 마지막에 원본 개체를 대체하는 데 사용할 수있는 최종 개체를 제공합니다.