?로 객체의 속성을 업데이트하는 것이 가능 setState
합니까?
다음과 같은 것 :
this.state = {
jasper: { name: 'jasper', age: 28 },
}
나는 시도했다 :
this.setState({jasper.name: 'someOtherName'});
이:
this.setState({jasper: {name: 'someothername'}})
첫 번째 구문 오류가 발생하고 두 번째는 아무것도 수행하지 않습니다. 어떤 아이디어?
답변
상태 업데이트는 비동기 작업 이므로 여러 가지 방법이 있으므로 상태 객체를 업데이트하려면 업데이터 함수를와 함께 사용해야 합니다setState
.
1- 가장 간단한 것 :
먼저 사본을 jasper
만든 다음 다음과 같이 변경하십시오.
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper); // creating copy of state variable jasper
jasper.name = 'someothername'; // update the name property, assign a new value
return { jasper }; // return new object jasper object
})
사용하는 대신 Object.assign
다음과 같이 작성할 수도 있습니다.
let jasper = { ...prevState.jasper };
2- 스프레드 연산자 사용 :
this.setState(prevState => ({
jasper: { // object that we want to update
...prevState.jasper, // keep all other key-value pairs
name: 'something' // update the value of specific key
}
}))
참고 : Object.assign
및 Spread Operator
단지 생성 얕은 사본을 중첩 된 객체 또는 객체의 배열을 정의 그렇다면, 당신은 다른 접근 방식이 필요합니다.
중첩 된 상태 객체 업데이트 :
상태를 다음과 같이 정의했다고 가정하십시오.
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
피자 개체의 extraCheese를 업데이트하려면 :
this.setState(prevState => ({
food: {
...prevState.food, // copy all other key-value pairs of food object
pizza: { // specific object of food object
...prevState.food.pizza, // copy all pizza key-value pairs
extraCheese: true // update value of specific key
}
}
}))
객체 배열 업데이트 :
할 일 앱이 있고 다음 형식으로 데이터를 관리한다고 가정합니다.
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
할 일 객체의 상태를 업데이트하려면 배열에서 맵을 실행하고 각 객체의 고유 한 값을 확인하십시오.의 경우 condition=true
업데이트 된 값을 가진 새 객체를 반환하고 그렇지 않으면 동일한 객체를 반환하십시오.
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
제안 : 객체에 고유 한 값이 없으면 배열 색인을 사용하십시오.
답변
가장 빠르고 읽기 쉬운 방법입니다.
this.setState({...this.state.jasper, name: 'someothername'});
this.state.jasper
이미 이름 속성이 포함되어 있어도 새 이름 name: 'someothername'
이 사용됩니다.
답변
스프레드 연산자와 일부 ES6을 사용하십시오.
this.setState({
jasper: {
...this.state.jasper,
name: 'something'
}
})
답변
이 솔루션을 사용했습니다.
다음과 같이 중첩 된 상태 인 경우 :
this.state = {
formInputs:{
friendName:{
value:'',
isValid:false,
errorMsg:''
},
friendEmail:{
value:'',
isValid:false,
errorMsg:''
}
}
}
현재 상태를 복사하고 변경된 값으로 재 할당하는 handleChange 함수를 선언 할 수 있습니다.
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let statusCopy = Object.assign({}, this.state);
statusCopy.formInputs[inputName].value = inputValue;
this.setState(statusCopy);
}
이벤트 리스너가있는 html입니다. 상태 객체에 사용 된 것과 동일한 이름 (이 경우 ‘friendName’)을 사용해야합니다.
<input type="text" onChange={this.handleChange} " name="friendName" />
답변
여기에 많은 답변이 있다는 것을 알고 있지만 setState 외부에서 새 객체의 복사본을 만든 다음 단순히 setState ({newObject})를 작성하는 사람이 아무도 없습니다. 깨끗하고 간결하며 신뢰할 수 있습니다. 따라서이 경우 :
const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(() => ({ jasper }))
또는 동적 속성 (매우 유용한 양식)
const jasper = { ...this.state.jasper, [VarRepresentingPropertyName]: 'new value' }
this.setState(() => ({ jasper }))
답변
이것을 시도하십시오, 그것은 잘 작동합니다
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
답변
첫 번째 경우는 실제로 구문 오류입니다.
나머지 구성 요소를 볼 수 없기 때문에 왜 여기에 상태에 객체를 중첩시키는 지 알기가 어렵습니다. 구성 요소 상태에 개체를 중첩시키는 것은 좋지 않습니다. 초기 상태를 다음과 같이 설정하십시오.
this.state = {
name: 'jasper',
age: 28
}
이렇게하면 이름을 업데이트하려면 다음을 호출하면됩니다.
this.setState({
name: 'Sean'
});
그것이 당신이 목표로하는 것을 달성 할 것입니까?
더 크고 복잡한 데이터 저장소의 경우 Redux와 같은 것을 사용합니다. 그러나 훨씬 더 발전했습니다.
구성 요소 상태의 일반적인 규칙은 구성 요소의 UI 상태 (예 : 활성, 타이머 등)를 관리하는 데만 사용하는 것입니다.
다음 참조를 확인하십시오.