Это вообще возможно, чтобы обновить объект's свойства при выполнении функция setState?
Что-то вроде:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Я пробовал:
this.setState({jasper.name: 'someOtherName'});
и это:
this.setState({jasper: {name: 'someothername'}})
Первые результаты в синтаксическую ошибку, а второй просто ничего не делает. Любые идеи?
Существует несколько способов сделать это, поскольку государство обновление асинхронной операции, поэтому для обновления состояния объекта, мы должны использовать функция обновления с выполнении функция setState
.
1 - Простое:
Сначала создайте копию яшма
, затем сделать изменения в том, что:
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
})
Вместо того, чтобы использовать объект.назначить мы также можем записать это так:
let jasper = { ...prevState.jasper };
2 - с помощью [распространения оператора]3:
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
}
}))
Примечание: `Объект.назначить " и " распространение оператор создает только копию, поэтому, если вы определили вложенный объект или массив объектов, вам нужен другой подход.
Обновление # вложенного состояния объекта:
Предположим, вы определили состояние как:
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
}
}
}))
Допустим, у вас есть todo приложение, и вы управляете данные в таком виде:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
Чтобы обновить состояние любого объекта, задач, запустить карту на массив и проверять по некоторым уникальным значением каждого элемента, в случае, если условие=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'});
Даже если это есть.государства.Джаспер уже содержит свойство, новое имя `имя: 'someothername' С быть использован.
Я использовал это решение.
Если у вас есть вложенные государством такой:
это.состояние = { formInputs:{ friendName:{ значение:'', функция IsValid:ложные, errorMsg:'' }, friendEmail:{ значение:'', функция IsValid:ложные, 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.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
В первом случае это действительно ошибка синтаксиса.
Поскольку я могу'т см. Остальные компонента, это's жесткий, чтобы увидеть, почему вы'вэ объекты, гнездящихся в вашем положении здесь. Это's не хорошая идея, чтобы объекты гнездо в компоненте государства. Попробуйте установить исходное состояние, чтобы быть:
this.state = {
name: 'jasper',
age: 28
}
Таким образом, если вы хотите изменить имя, вы можете просто позвонить:
this.setState({
name: 'Sean'
});
Это добиться того, что вы'вновь целился?
Для больших, более сложных хранилищ данных, я хотел бы использовать что-то вроде "возвращение". Но, что'ы гораздо более продвинутые.
Общее правило с составляющую государственную, чтобы использовать его только для управления состоянием пользовательского интерфейса компонента (например, активный, таймеры и др.).
Проверьте эти ссылки:
Другой вариант: определить переменную из яшма объект и потом просто назвать переменную.
Распространение оператор: ЕС6
this.state = { jasper: { name: 'jasper', age: 28 } }
let foo = "something that needs to be saved into state"
this.setState(prevState => ({
jasper: {
...jasper.entity,
foo
}
})
Я знаю, что есть много ответов здесь, но я'м удивлены, что никто из них создать экземпляр нового объекта за пределами выполнении функция setState, а потом просто выполнении функция setState({переменная newobject}). Чистый, лаконичный и надежный. Так в этом случае:
в
const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(prevState => ({ jasper }))
в
Или для динамического свойства (очень полезно для форм)
в
в
константный Джаспер = { ...этого.государства.Джаспер, [VarRepresentingPropertyName]: 'новое значение' } это.выполнении функция setState(prevState => ({ яшма }))
в
Вы можете попробовать с этим:
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}
/>
Вы можете попробовать с этим: (Примечание: имя тега input === поле объекта) `` <входное имя="в поля myfield, что" типа=на"текст" и значение={этот.государства.мой_объект.поля myfield} onChange, после={этот.handleChangeInpForm}> </вход>
handleChangeInpForm = (е) => { пусть переменная newobject = это.государства.объект MyObject; переменная newobject[электронный.цель.имя] = Эл.цель.значение; это.выполнении функция setState({ мой_объект: переменная newobject }) } ``
Простой и динамичный способ.
Это будет делать эту работу, но вам нужно установить все эти идентификаторы родителя, родитель будет указать имя объекта, свой паспорт = то "Яшма" и имя элемента input = собственность внутри объекта Джаспер.
handleChangeObj = ({target: { id , name , value}}) => this.setState({ [id]: { ...this.state[id] , [name]: value } });
Без использования async и await используйте это...
funCall(){
this.setState({...this.state.jasper, name: 'someothername'});
}
Если вы с помощью async и await используйте это...
async funCall(){
await this.setState({...this.state.jasper, name: 'someothername'});
}
Кроме того, после Альберто Пирас решение, если вы не'т хотите скопировать всех "государства" по объекту:
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});
}
это еще одно решение с использованием Иммер утилиты immutabe, очень подходит для глубоко вложенные объекты с легкостью, и вы не должны заботиться о мутации
this.setState(
produce(draft => {
draft.jasper.name = 'someothername
})
)