Обновление объекта с setState в реагируешь

Это вообще возможно, чтобы обновить объект's свойства при выполнении функция setState?

Что-то вроде:

this.state = {
   jasper: { name: 'jasper', age: 28 },
}

Я пробовал:

this.setState({jasper.name: 'someOtherName'});

и это:

this.setState({jasper: {name: 'someothername'}})

Первые результаты в синтаксическую ошибку, а второй просто ничего не делает. Любые идеи?

Комментарии к вопросу (1)
Решение

Существует несколько способов сделать это, поскольку государство обновление асинхронной операции, поэтому для обновления состояния объекта, мы должны использовать функция обновления с выполнении функция 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
  )

}))

Примечание: Если объект не'т иметь уникальное значение, а затем использовать индекс массива.

Комментарии (11)

Это самый быстрый и самый четкий способ:

this.setState({...this.state.jasper, name: 'someothername'});

Даже если это есть.государства.Джаспер уже содержит свойство, новое имя `имя: 'someothername' С быть использован.

Комментарии (1)

Использование оператора распространения и некоторых ЕС6 здесь

this.setState({
    jasper: {
          ...this.state.jasper,
          name: 'something'
    }
})
Комментарии (1)

Я использовал это решение.

Если у вас есть вложенные государством такой: это.состояние = { 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" />
Комментарии (0)

попробуйте этот,он должен работать нормально

this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
Комментарии (1)

В первом случае это действительно ошибка синтаксиса.

Поскольку я могу'т см. Остальные компонента, это's жесткий, чтобы увидеть, почему вы'вэ объекты, гнездящихся в вашем положении здесь. Это's не хорошая идея, чтобы объекты гнездо в компоненте государства. Попробуйте установить исходное состояние, чтобы быть:

this.state = {
  name: 'jasper',
  age: 28
}

Таким образом, если вы хотите изменить имя, вы можете просто позвонить:

this.setState({
  name: 'Sean'
});

Это добиться того, что вы'вновь целился?

Для больших, более сложных хранилищ данных, я хотел бы использовать что-то вроде "возвращение". Но, что'ы гораздо более продвинутые.

Общее правило с составляющую государственную, чтобы использовать его только для управления состоянием пользовательского интерфейса компонента (например, активный, таймеры и др.).

Проверьте эти ссылки:

Комментарии (2)

Другой вариант: определить переменную из яшма объект и потом просто назвать переменную.

Распространение оператор: ЕС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
    }
})
Комментарии (1)

Я знаю, что есть много ответов здесь, но я'м удивлены, что никто из них создать экземпляр нового объекта за пределами выполнении функция setState, а потом просто выполнении функция setState({переменная newobject}). Чистый, лаконичный и надежный. Так в этом случае:

в

const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(prevState => ({ jasper }))

в

Или для динамического свойства (очень полезно для форм)

в

в

константный Джаспер = { ...этого.государства.Джаспер, [VarRepresentingPropertyName]: 'новое значение' } это.выполнении функция setState(prevState => ({ яшма }))

в

Комментарии (0)

Вы можете попробовать с этим:

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}
/>
Комментарии (1)

Вы можете попробовать с этим: (Примечание: имя тега input === поле объекта) `` <входное имя="в поля myfield, что" типа=на"текст" и значение={этот.государства.мой_объект.поля myfield} onChange, после={этот.handleChangeInpForm}> </вход>


handleChangeInpForm = (е) => { пусть переменная newobject = это.государства.объект MyObject; переменная newobject[электронный.цель.имя] = Эл.цель.значение; это.выполнении функция setState({ мой_объект: переменная newobject }) } ``

Комментарии (1)

Простой и динамичный способ.

Это будет делать эту работу, но вам нужно установить все эти идентификаторы родителя, родитель будет указать имя объекта, свой паспорт = то "Яшма" и имя элемента input = собственность внутри объекта Джаспер.

handleChangeObj = ({target: { id , name , value}}) => this.setState({ [id]: { ...this.state[id] , [name]: value } });
Комментарии (0)

Без использования async и await используйте это...

funCall(){    
     this.setState({...this.state.jasper, name: 'someothername'});
}

Если вы с помощью async и await используйте это...

async funCall(){
      await this.setState({...this.state.jasper, name: 'someothername'});
}
Комментарии (0)

Кроме того, после Альберто Пирас решение, если вы не'т хотите скопировать всех "государства" по объекту:

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});
  }
Комментарии (0)

это еще одно решение с использованием Иммер утилиты immutabe, очень подходит для глубоко вложенные объекты с легкостью, и вы не должны заботиться о мутации

this.setState(
    produce(draft => {
       draft.jasper.name = 'someothername
    })
)
Комментарии (0)