Как правильно установить состояние вложенных объектов в Reactjs? - PullRequest
0 голосов
/ 08 апреля 2019

Этот фрагмент кода копирует мою проблему из программного обеспечения, над которым я сейчас работаю в этой компании X.

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React',
      some:{
        name:"axys",
        a:[1,2.23,46,612,5],
        z:{
          a:2,
          b:5,
          c:6,
        }
      }
    };
  }

handler = () =>{
  console.log(this.state);
  this.setState({
    some:{
      z:{
        a:1111
      }
    }
  },()=>{
    console.log(this.state);
  })
}

  render() {
    return (
      <div>
        <Hello name={this.state.name} />
        <button onClick = {this.handler}>
          Change State
        </button>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

Допустим, я хочу изменить значение this.state.some.zaТо, что я изначально был

this.setState({
    some:{
      z:{
        a:1111
      }
    }
}

Но оказалось, что мне возвращено состояние

{
  "name": "React",
  "some": {
    "z": {
      "a": 1111
    }
  }
}

Так что для получения намеченного результата мне нужно написать

this.setState({
    some:{
      ...this.state.some,
      z:{
        ...this.state.some.z,
        a:1111
      }
    }
  }

Так что мой вопрос в том, является ли это правильным / рекомендуемым способом выполнения действий или я что-то упускаю.

Если это правильный путь, не будет ли зависеть от производительности setState от оператора распространения (...)

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Есть несколько способов сделать то, что вы пытаетесь сделать, как уже упоминали другие.Но правильный способ сделать так, как вы упомянули, заключается в использовании prevState, так как this.state ненадежен (потому что он асинхронный).

Вот рабочие примеры:

this.setState((prevState, props) => ({
  some: {
    ...prevState.some,
    z: {
      ...prevState.some.z,
      a: 1111
    }
  }
}))

Отличное объяснение: https://teamtreehouse.com/community/react-docs-now-recommends-using-function-with-prevstate-inside-of-setstate

0 голосов
/ 08 апреля 2019
there are two ways to do it 

1. copy the object into some:

    handler = () => {
        let some = Object.assign({}, this.state.some);
        some.z.a = 1111;
        this.setState({ some }, () => {
          console.log(this.state);
        });
      };

will give an output:

    {
    name: "React"
    some: Object
    name: "axys"
    a: Array[5]
    z: Object
    a: 1111
    b: 5
    c: 6}

2. using the spead oprator
    handler = () => {
        let some = { ...this.state.some };
        console.log(some)
        this.setState(
          prevstate => ({
            some: {
             z:{ ...prevstate.some.z,
              a: 1111}
            }
          }),
          () => {
            console.log(this.state);
          }
        );
      };

with solution:

    {name: "React"
    some: Object
    z: Object
    a: 1111
    b: 5
    c: 6}
hope it will help
...