为什么在反应中以状态存储数据

Ami*_*esh 5 javascript reactjs

我想了解如果我们不将数据存储在state. 我们仍然可以通过使用触发重新渲染this.setState({})。请提供深入分析。

请注意,我不关心维护应用程序的状态(通常通过 Redux、Mobx 等完成)

class App extends React.Component {
  constructor() {
    super();
    // this.state = { counter: 0 };//Am I loosing something by not doing in this way
  }
  counter = 0;
  increment() {
    this.counter++;
    this.setState({});//trigger re-render as new object is set to state
    // this.state.counter++;
    // this.setState(this.state);
  }

  render() {
    return (
      <div>
        <h2>Click button to increament counter</h2>
        <button type="button" onClick={()=>this.increament()}>{this.counter}</button>
      </div>
    );
  }
}
//export default App;

ReactDOM.render(
  <App />,
  document.body
);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

xpr*_*nio 6

您将失去的最大的事情之一是生命周期方法和可维护性。React 背后的整个想法state是使该组件和从该状态传递数据的任何子组件中的数据更容易保持同步,但是要使所有这些按预期工作,您需要使用更新状态this.setState()并从中读取它通过this.state

React 在调用时所做的this.setState()(除了更新状态)也经历了必要的生命周期步骤。它所做的主要事情之一是重新渲染组件(及其子组件),但正如您所说,您可以触发使用this.setState({})which 在某种程度上是正确的,但前提是您也可以接受丢失:

表现

JavaScript 速度很快。反应很快。当你快速与快速交叉时,你会得到什么?我不知道,但它可能真的很快。特别是如果你喜欢使用作出反应的PureComponent,这是完全一样的Component,差异在于PureComponent工具shouldComponentUpdate使用浅状态和道具比较,而Component没有。这意味着如果您不更新任何内容(状态和道具都保持不变),PureComponent则不会重新渲染组件,而Component会。如果不使用 React 的状态系统,则无法真正使用PureComponent以获得更好的性能,也无法实现shouldComponentUpdate,因为您无法将旧数据与新数据进行比较。您必须自己重新实现该性能功能。

稳定

告别 React 的状态系统转而采用 hacky 的解决方案也意味着告别应用程序的稳定性,并向未来的更多问题问好。让我们从上面的角度来解决性能问题,让我们把它们放大。为了让您拥有更高性能的应用程序,您必须对整个应用程序重复上述操作,或者创建一个可以跨组件重复使用的通用解决方案。更不用说this.setState({})每次更新数据时记得调用,只是为了让组件重新渲染。忘记它一次,您的应用程序将开始显示不一致的数据,因为即使“您的状态”更新了,React 的状态也没有。扩大规模,你就会遇到问题。

不想伤害你的同事

面对现实吧。你可能是编程新手,React 新手,或者没有在团队中工作过,没关系,我们都是从某个地方开始的。然而,真正重要的是不要让你的团队想要伤害你,以至于你不得不选择一个新的专业。一种不需要手指和/或眼睛的。使用久经考验的框架以及正确使用它们的好处是每个人都可以减少麻烦。没有人必须为已经存在的用例创建和维护hacky解决方案。由于渲染不一致,没有人必须撕掉头发。没有人必须失去一只眼睛或折断任何手指,因为有人认为重新发明轮子是个好主意,但这次是作为一个立方体。

TL; DR & 最后的话

  1. 不要重新发明轮子。它已经存在,它是圆的
  2. 聪明地工作,而不是努力
  3. 要么使用 React 的内置状态系统,要么使用Redux/MobX(参见 1.)
  4. 使用this.setState用于更新,this.state阅读。不要直接改变 state,因为 React 不会调用任何生命周期方法,导致意外行为和错误


Olu*_*ule 1

在组件实例上设置组件状态可能会导致组件出现错误,并影响组件的可维护性。

无法保证组件状态的正确性

如果生成点击的速度快于this.counter增量的速度,则不能保证计算结果counter是正确的

setState保证对它的多个调用被批量地一起应用。因此,counter价值是有保证的。

this.setState(prevState => ({counter: prevState.counter + 1}))
Run Code Online (Sandbox Code Playgroud)

渲染逻辑与状态突变没有分离

此外,在组件状态未更改时必须避免渲染的用例中,捕获下一个状态React.Component之类的生命周期方法shouldComponentUpdate有效地将渲染决策从更新到状态分开。

保持组件实例的状态将使您计算下一个状态,将其与前一个状态进行比较并决定是否强制重新渲染。如果您有更多的组件状态需要管理,这可能会变得难以维护。