您是否应该在构造函数中定义组件状态的所有属性?

时间:2018-07-13 21:28:45

标签: javascript reactjs v8

因此,我读完了this article,基本上讨论了v8和其他JavaScript引擎如何在内部缓存对象的“形状”,以便当他们需要重复访问对象上的特定属性时,可以使用直接内存地址,而不是查找该对象在该内存中的特定属性。

这让我开始思考,在React中,您经常在构造函数中声明组件的状态,但并不包括最终会包含在状态中的所有属性,例如:

class MyComponent extends React.Component {
   constructor(props) {
       super(props);
       this.state = {
          hasLoaded: false
       };
   }

   componentDidMount() {
       someAjaxRequest.then((response) => {
           this.setState({
              content: response.body,
              hasLoaded: true
           });
       });
   }

   render() {
       return this.state.hasLoaded ?
          <div>{this.state.content}</div> :
          <div>Loading...</div>;
   }
}

由于根据本文所述,状态对象不会保持一致的结构,因此这样做比在构造函数中定义所有可能的状态字段效率低吗?您是否应该始终至少添加所有属性,甚至为其赋予值null,以使对象始终保持一致? 这会对性能产生重大影响吗?

4 个答案:

答案 0 :(得分:5)

TL; DR表现的提升似乎微不足道,以至于真的不值得。

测试设置:

我为这堂课赚了100,000个孩子:

import React, { Component } from 'react';

const getRand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

class Child extends Component {
  constructor() {
    super();
    this.state = {
      loading: false,
    };
  }

  componentDidMount() {
    const key = getRand(1, this.props.numKeys);
    this.setState({
      key,
      [key]: 'bar',
    });
  }

  render() {
    if (this.props.display) {
      return <div>child {this.state.key} {this.state[this.state.key]}</div>
    }
    return <div>child 0</div>
  }
}

export default Child;

孩子的构成如下:

const children = [];
for (let i = 0; i < 1 * 100 * 1000; i++) {
  children.push(<Child display={true} numKeys={1000} key={i} />);
}
return (
  <div>
    {children}
  </div>
);

想法是:我可以传入display道具来为每个孩子呈现相同的HTML或不同的HTML。

我还传递了numKeys来确定对象上应该有多少种不同类型的键。经过测试,display道具并没有显着影响DOM渲染时间,因此我在下面没有进行报告。所有测试均通过yarn build && serve -s buildcreate-react-app一起运行

结果

所有孩子的钥匙都相同

Same key for all children

所有孩子的3个键

3 keys for all children

所有孩子的10个按键

10 keys for all children

所有孩子的1000个钥匙

1000 keys for all children * Chrome 67.0.3396.99中的所有测试

如您所见,在您拥有许多不同形状的对象之前,100,000个对象的性能可以忽略不计。即使这样,您在100,000个组件上的性能提升还是700ms,或者每个组件7微秒。当然不是声称的8倍加速。

更多:在任何现实的情况下,DOM操作可能会使您的渲染时间相形见and,而不是像此测试那样综合。

答案 1 :(得分:2)

除了进行优化之外,最好将所有本地状态字段建模,即使您提到的只是npm start -- --reset-cache。这样,您可以通过简单调用rm -rf /tmp/haste-map-react-native-packager-*将组件重置回其初始状态。

答案 2 :(得分:0)

为了优化和提高性能,始终建议在构造函数中初始化所有组件变量,以便在组件中加载初始值,并避免在运行时创建新的状态变量。

答案 3 :(得分:0)

预先定义所有属性的主要原因是,它充当组件的self documenting功能。

所以

  1. 它减少了添加评论的需要
  2. 它减少了开发人员熟悉组件所需的时间

这样做的长期时间/维护收益将物有所值,不考虑性能收益。