在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()更改为这个。state ={}(谢谢joews),然而,我仍然没有看到区别。哪个更好?
在构造函数中从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} />
);
}
}
或者使用关键道具作为初始化的触发器:
class SecondComponent extends React.Component {
state = {
// initialize using props
};
}
<SecondComponent key={something} ... />
在上面的代码中,如果发生了变化,那么SecondComponent将作为一个新实例重新挂载,状态将由props初始化。
React 16.3 alpha的更新引入了静态getDerivedStateFromProps(nextProps, prevState) (docs)作为componentWillReceiveProps的替换。
getDerivedStateFromProps在组件实例化之后以及在它接收到新道具时调用。它应该返回一个对象来更新状态,或者返回null来表示新的道具不需要任何状态更新。
注意,如果父组件导致你的组件重新呈现,即使道具没有改变,这个方法也会被调用。如果您只想处理更改,则可能希望比较新的值和以前的值。
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
它是静态的,因此它不能直接访问this(但是它可以访问prevState,它可以存储通常附加到this的东西,例如refs)
编辑以反映@nerfologist在评论中的更正
在构造函数中从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} />
);
}
}
或者使用关键道具作为初始化的触发器:
class SecondComponent extends React.Component {
state = {
// initialize using props
};
}
<SecondComponent key={something} ... />
在上面的代码中,如果发生了变化,那么SecondComponent将作为一个新实例重新挂载,状态将由props初始化。