Возможно ли вообще обновить свойства объекта с помощью setState?
Что-то вроде:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Я пробовал:
this.setState({jasper.name : 'someOtherName'});
и это:
this.setState({jasper:{name:'someothername'}})
Первая - это синтаксическая ошибка, а вторая ничего не делает. Любые идеи?
Существует несколько способов сделать это.
1- Самый простой:
Сначала создайте копию jasper
, затем выполните изменения в этом:
let jasper = Object.assign({}, this.state.jasper); //creating copy of object
jasper.name = 'someothername'; //updating value
this.setState({jasper});
Вместо использования Object.assign
мы также можем записать его следующим образом:
let jasper = {...this.state.jasper};
2- Используя оператор распространения:
this.setState(prevState => ({
jasper: {
...prevState.jasper,
name: 'something'
}
}))
jasper
объекта, сделать console.log(jasper)
вы увидите только одно ключевое name
, возраст не будет там :)
Самый быстрый и самый читаемый способ:
this.setState({...this.state.jasper, name: 'someothername'});
Несмотря на то, что this.state.jasper
уже содержит свойство name, следует использовать последнее name: 'someothername'
.
this.state.jasper
не обязательно содержит последнее состояние. Лучше использовать обозначения с prevState
.
Используйте оператор распространения и немного 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" />
Первый случай - действительно синтаксическая ошибка.
Так как я не вижу остальных компонентов, трудно понять, почему вы размещаете объекты в своем состоянии здесь. Неплохо встраивать объекты в состояние компонента. Попробуйте установить начальное состояние:
this.state = {
name: 'jasper',
age: 28
}
Таким образом, если вы хотите обновить имя, вы можете просто вызвать:
this.setState({
name: 'Sean'
});
Достигнет ли это того, к чему вы стремитесь?
Для больших, более сложных хранилищ данных я бы использовал что-то вроде Redux. Но это гораздо более продвинутый.
Общее правило с состоянием компонента - использовать его только для управления состоянием пользовательского интерфейса компонента (например, активным, таймерам и т.д.).
Проверьте эти ссылки:
попробуйте это, оно должно работать нормально
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
Вы можете попробовать это: (Примечание: имя входного тега === поле объекта)
<input name="myField" type="text"
value={this.state.myObject.myField}
onChange={this.handleChangeInpForm}></input>
-----------------------------------------------------------
handleChangeInpForm = (e) => {
let newObject = this.state.myObject;
newObject[e.target.name] = e.target.value;
this.setState({
myObject: newObject
})
}
Вы можете попробовать это:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.name = 'someOtherName';
return {jasper: prevState}
})
или для другого имущества:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.age = 'someOtherAge';
return {jasper: prevState}
})
Или вы можете использовать функцию handleChage:
handleChage(event) {
const {name, value} = event.target;
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState[name] = value;
return {jasper: prevState}
})
}
и HTML-код:
<input
type={"text"}
name={"name"}
value={this.state.jasper.name}
onChange={this.handleChange}
/>
<br/>
<input
type={"text"}
name={"age"}
value={this.state.jasper.age}
onChange={this.handleChange}
/>
Также, следуя решению Альберто Пираса, если вы не хотите копировать весь объект "состояние":
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let jasperCopy = Object.assign({}, this.state.jasper);
jasperCopy[inputName].name = inputValue;
this.setState({jasper: jasperCopy});
}
Другой вариант: определить вашу переменную из объекта Jasper, а затем просто вызвать переменную.
Оператор спреда: ES6
this.state = { jasper: { name: 'jasper', age: 28 } }
let foo = "something that needs to be saved into state"
this.setState(prevState => ({
jasper: {
...jasper.entity,
foo
}
})
foo
расширяется до foo: foo
...
age
внутриjasper
.