在调用 setState() 之前直接改变状态可以吗?

IT技术 reactjs typescript
2021-04-27 15:14:50

我正在使用轻量级 ORM 将我的 React 应用程序与外部服务连接起来……这个包返回模型的对象,并允许您直接对它们执行操作。虽然这真的很棒,但我很难弄清楚如何将这些对象包含进来state并仍然遵循 react 的“从不直接修改状态”租户。

如果我有一个更新帐户名称的组件,这样做是否可以接受?

interface IAppState {
  account: Account
}

class App extends React.Component<{}, IAppState> {
  constructor(props) {
    super(props);
    this.state = {
      account: new Account()
    }
  }

  //set the new name and update the external service
  public updateAccount = (newName: string)=>{
    account.name = newName; //REDFLAG!!!
    acc.update().then(()=>{
        this.setState({ account: this.state.account })
    })
  }

  //retrieve our account object from external service
  public componentDidMount() {
    const qParams = queryString.parse(window.location.search);
    Account.get(qParams.externalId).then((acc)=>{
        this.setState({account: acc})
    })
  }

  render() {
    return <NameEditor handleClick={this.updateAccount} account={a} />
    }
 }

我想我可以通过启动一个空白的 ORM 对象、复制属性、发送更新然后设置状态来避免改变状态,但这似乎是一个主要的痛苦..特别是因为这些 ORM 对象可以包含我想要的子 ORM 对象喜欢也可以修改。

我是在“危险”或“不良形式”之上改变状态的方式吗???

更新

做了一些阅读,它肯定看起来这可能是错误的形式,可以使用react/addons...优雅地导航...但是,如果 ORM 调用对对象有副作用怎么办?例如,调用insert设置对象的外部 id 字段。

2个回答
public updateAccount = (newName: string)=>{
    //account.name = newName; //REDFLAG!!!
    // You can use the below code to update name after it is updated
    // on server.
    // This will work because the object being passed here
    // will be merged with Component state.
    acc.update().then(()=>{
        this.setState({account: {name : newName}})
    })
}

不建议直接修改状态,因为 react 不会知道更改,也不会导致重新渲染。

所有的差异都发生在 Virtual DOM 上,react 只更新浏览器 DOM 的更改属性。您可以在此处阅读有关react差异算法的更多信息

React 建议使用不可变对象来设置状态。为此,您可以使用 Object.assign 或 immutable.js,这将使我们的生活更轻松。如果你改变你的状态对象,它会影响你的react组件的性能。

您可以参考以下链接了解更多信息。

https://facebook.github.io/react/docs/optimizing-performance.html#examples