3

我正在尝试更新包含多个级别的状态对象。请参阅此示例https://codesandbox.io/s/oq9kp9vy5y

问题是,渲染方法中的值不会更新......只有第一个。我可以强制更新还是有更好的方法?

谢谢卡斯帕

4

3 回答 3

6

在您的初始状态下,您拥有kitchen对象内部calculatedUsage对象。但是在您的setState通话中,您的kitchen对象位于.calculatedUsage

此外,当您访问 中的先前状态时setState,最好使用 的功能版本setState,例如:

componentDidMount() {
  this.setState(
    prevState => ({
      caclulatedUsage: {
        ...prevState.caclulatedUsage,
        bath: 12,
        kitchen: {
          ...prevState.caclulatedUsage.kitchen,
          stove: 14,
          fridge: 23,
          dishwasher: 34
        }
      }
    }),
    () => {
      console.log(this.state);
    }
  );
}

这样做的原因是它setState可以是异步的,这意味着this.state在其中访问可能不会给您期望的值。使用功能版本进行事务状态更改可确保结果一致。

您可能还想看看immer库。通过允许您使用可变 API 进行不可变更新,它使更新深度嵌套的状态变得更加容易。这是使用 immer 的代码和框示例的一个分支: https ://codesandbox.io/s/180p7p0o84

于 2019-01-18T19:14:19.553 回答
2

尝试这样的事情

import React, { Component } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      caclulatedUsage: {
        bath: 0,
        kitchen: {
          stove: 0,
          fridge: 0,
          dishwasher: 0
        },
        livingroom: {
          tv: 0,
          tvBox: 0
        }
      }
    };
  }

  componentDidMount() {
    this.setState(
      {
        caclulatedUsage: Object.assign({}, this.state.access, {
          caclulatedUsage: {
            ...this.state.caclulatedUsage,
            bath: 12
          },
          kitchen: {
            ...this.state.caclulatedUsage.kitchen,
            stove: 14,
            fridge: 23,
            dishwasher: 34
          }
        })
      },
      () => {
        console.log(this.state);
      }
    );
  }

  render() {
    return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        {this.state.caclulatedUsage.bath}
        <br />
        {this.state.caclulatedUsage.kitchen.stove}
        <br />
        {this.state.caclulatedUsage.kitchen.fridge}
        <br />
        {this.state.caclulatedUsage.kitchen.dishwasher}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
于 2019-01-18T19:11:15.080 回答
0

尝试:

  componentDidMount() {
    this.setState(
      {
        caclulatedUsage: {
          ...this.state.caclulatedUsage,
          bath: 12,
           kitchen: {
               ...this.state.caclulatedUsage.kitchen,
               stove: 14,
               fridge: 23,
               dishwasher: 34
           }
        }

      }
      () => {
        console.log(this.state);
      }
    );
  }
于 2019-01-18T19:13:44.957 回答