Javascript 是否定义组件的所有属性';构造函数中的状态是什么?

Javascript 是否定义组件的所有属性';构造函数中的状态是什么?,javascript,reactjs,v8,Javascript,Reactjs,V8,所以我读完了这本书,它基本上讲述了v8和其他javascript引擎如何在内部缓存对象的“形状”,以便当它们需要重复访问对象上的特定属性时,它们可以使用直接内存地址,而不是查找该对象内存中该特定属性的位置 这让我想到,在React中,您经常在构造函数中声明组件的状态,但不包括最终将包含在状态中的所有属性,例如: class MyComponent extends React.Component { constructor(props) { super(props);

所以我读完了这本书,它基本上讲述了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>;
   }
}
类MyComponent扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ 已加载:错误 }; } componentDidMount(){ someAjaxRequest.then((响应)=>{ 这是我的国家({ 内容:response.body, 是的 }); }); } render(){ 是否返回此.state.hasload? {this.state.content}: 加载。。。; } }
因为根据文章,state对象并不保持一致的结构,这样做会比在构造函数中定义所有可能的state字段效率低吗?您是否应该至少添加所有属性,即使给它们一个值
null
,以便对象始终一致它会以任何实质性的方式影响性能吗?

除了优化之外,最好对所有本地状态字段建模,即使它只是
数据:null
。通过这种方式,只需调用
This.setState

TL;DR.这些性能上的胜利似乎微不足道,根本不值得

测试设置:

我为这个班培养了100000名学生:

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;
import React,{Component}来自'React';
常量getRand=(最小,最大)=>Math.floor(Math.random()*(max-min+1))+min;
类子扩展组件{
构造函数(){
超级();
此.state={
加载:false,
};
}
componentDidMount(){
const key=getRand(1,this.props.numKeys);
这是我的国家({
钥匙
[键]:“bar”,
});
}
render(){
如果(此.props.display){
返回子{this.state.key}{this.state[this.state.key]}
}
返回子0
}
}
导出默认子对象;
这些儿童的情况如下:

const children = [];
for (let i = 0; i < 1 * 100 * 1000; i++) {
  children.push(<Child display={true} numKeys={1000} key={i} />);
}
return (
  <div>
    {children}
  </div>
);
const children=[];
for(设i=0;i<1*100*1000;i++){
儿童。推();
}
返回(
{儿童}
);
其想法是:我可以传入
display
属性,为每个孩子呈现相同的HTML,或者呈现不同的HTML

我还传入了一个
numKeys
,以确定对象上应该有多少种不同类型的键。测试后,
display
prop对DOM渲染时间没有显著影响,因此我没有在下面报告它。所有测试均通过
create-react应用程序

结果 所有儿童使用相同的钥匙

为所有儿童提供3把钥匙

为所有儿童提供10把钥匙

为所有儿童提供1000把钥匙 *所有测试均采用铬67.0.3396.99

如您所见,在拥有大量不同形状的对象之前,100000个对象的性能可以忽略不计。即使如此,您的性能在100000个组件上增加了700毫秒,或每个组件增加了7微秒。这肯定不是声称的8倍加速比


此外:在任何现实的情况下,渲染时间都可能比DOM操作要短,并且不像此测试那样是合成的。

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

预先定义所有属性的主要原因是,它用作
自记录组件的功能

所以

  • 它减少了添加注释的需要
  • 它减少了开发人员熟悉组件所需的时间

  • 这样做的长期时间/维护收益将自付,性能收益除外。

    这是您可以通过做一些基准测试来测试自己的东西。根据我的经验,如果所有属性都是在构造函数中创建的,那么它的执行速度确实会更快。更不用说,如果你有默认值,你的同事和你自己在6个月内会更容易掌握你的状态。双赢,你这是什么意思?不带参数调用
    setState
    不会重置状态。React不知道组件的初始状态。正确,您必须使用默认状态值调用它,例如:
    this.setState({data:null})
    来重置它。