从组件反应组件初始化状态

2020/10/15 02:01 · javascript ·  · 0评论

在React中,这两种实现之间有什么真正的区别?一些朋友告诉我,FirstComponent是模式,但是我不明白为什么。SecondComponent似乎更简单,因为渲染仅被调用一次。

第一:

import React, { PropTypes } from 'react'

class FirstComponent extends React.Component {

  state = {
    description: ''
  }

  componentDidMount() {
    const { description} = this.props;
    this.setState({ description });
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} /> 
    );
  }
}

export default FirstComponent;

第二:

import React, { PropTypes } from 'react'

class SecondComponent extends React.Component {

  state = {
    description: ''
  }

  constructor (props) => {
    const { description } = props;
    this.state = {description};
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} />   
    );
  }
}

export default SecondComponent;

更新:我将setState()更改为this.state = {}(感谢joews),但是,我仍然看不到区别。一个比另一个好吗?

应当注意,复制永远不会更改为状态的属性是一种反模式(在这种情况下,只需直接访问.props即可)。如果您有一个状态变量最终会更改,但以.props中的值开头,则您甚至不需要构造函数调用-这些局部变量在调用父级的构造函数之后初始化:

class FirstComponent extends React.Component {
  state = {
    x: this.props.initialX,
    // You can even call functions and class methods:
    y: this.someMethod(this.props.initialY),
  };
}

这是等效于下面@joews中答案的简写。它似乎只能在最新版本的es6编译器上运行,在某些Webpack设置中我遇到了问题。如果这对您不起作用,则可以尝试添加babel插件babel-plugin-transform-class-properties,也可以使用下面@joews提供的非简写版本。

您不需要调用setStateComponent的constructor-this.state直接设置是惯用法

class FirstComponent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      x: props.initialX
    };
  }
  // ...
}

参见React docs-向类添加局部状态

您描述的第一种方法没有任何优势。它将在首次安装组件之前立即进行第二次更新。

更新了React 16.3 alpha static getDerivedStateFromProps(nextProps, prevState)文档),以替代componentWillReceiveProps

实例化组件之后以及接收到新的道具时,将调用getDerivedStateFromProps。它应该返回一个对象来更新状态,或者返回null来指示新道具不需要任何状态更新。

请注意,如果父组件导致您的组件重新渲染,即使道具没有更改,也会调用此方法。如果只想处理更改,则可能需要比较新值和先前值。

https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

它是静态的,因此它不具有直接访问this(但是它确实可以访问prevState,这可能会存储的东西通常连接到thisrefs

编辑以在评论中反映@nerfologist的更正

如果要添加所有道具以声明并保留相同的名称,则可以使用如下所示的简短形式。

constructor(props) {
    super(props);
    this.state = {
       ...props
    }
    //...
}

像这样在构造函数中设置状态数据

constructor(props) {
    super(props);
    this.state = {
      productdatail: this.props.productdetailProps
    };
}

如果您componentDidMount()通过道具设置辅助方法,它将无法正常工作

如果您直接通过道具初始化状​​态,它将在React 16.5中显示警告(2018年9月5日)

您必须时初始化要小心state来自props于构造函数。即使props更改为新状态,也不会更改状态,因为安装不再发生。因此getDerivedStateFromProps存在。

class FirstComponent extends React.Component {
    state = {
        description: ""
    };
    
    static getDerivedStateFromProps(nextProps, prevState) {
        if (prevState.description !== nextProps.description) {
          return { description: nextProps.description };
        }
    
        return null;
    }

    render() {
        const {state: {description}} = this;    

        return (
            <input type="text" value={description} /> 
        );
    }
}

或使用key道具作为初始化触发器:

class SecondComponent extends React.Component {
  state = {
    // initialize using props
  };
}
<SecondComponent key={something} ... />

在上面的代码中,如果something更改,SecondComponent则将重新安装为新实例,state并由初始化props

您可以key在需要时使用值来重置状态,通过props来声明这不是一个好习惯,因为您在一处拥有不受控制的组件。数据应放在一个地方处理,请参阅以下
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrol-component-with-a -键

您可以使用componentWillReceiveProps。

constructor(props) {
    super(props);
    this.state = {
      productdatail: ''
    };
}

componentWillReceiveProps(nextProps){
    this.setState({ productdatail: nextProps.productdetailProps })
}
本文地址:http://javascript.askforanswer.com/congzujianfanyingzujianchushihuazhuangtai.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!