Lev*_*ira 168 javascript components reactjs
在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;
Run Code Online (Sandbox Code Playgroud)
第二:
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;
Run Code Online (Sandbox Code Playgroud)
更新:我将setState()更改为this.state = {}(感谢joews),但是,我仍然没有看到区别.一个比其他更好吗?
Zan*_*per 167
应该注意的是,复制永不改变状态的属性是一种反模式(在这种情况下只是直接访问.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),
};
}
Run Code Online (Sandbox Code Playgroud)
这是一个简写等同于@joews下面的答案.它似乎只适用于更新版本的es6转换器,我在一些webpack设置上遇到了问题.如果这对您不起作用,您可以尝试添加babel插件babel-plugin-transform-class-properties
,或者您可以使用@joews下面的非简写版本.
joe*_*ews 126
你不需要调用setState
组件constructor
- 它是this.state
直接设置的惯用语:
class FirstComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
x: props.initialX
};
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
您描述的第一种方法没有任何优势.在第一次安装组件之前,它将立即进行第二次更新.
Ash*_*man 32
更新React 16.3 alpha引入static getDerivedStateFromProps(nextProps, prevState)
(docs)作为替代品componentWillReceiveProps
.
在实例化组件之后以及在接收新的props时调用getDerivedStateFromProps.它应该返回一个更新状态的对象,或者返回null以指示新的props不需要任何状态更新.
请注意,如果父组件导致组件重新渲染,即使props没有更改,也会调用此方法.如果您只想处理更改,则可能需要比较新值和以前的值.
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
它是静态的,因此它没有直接访问权限this
(但它有权访问prevState
,可以存储通常附加到的东西,this
例如refs
)
编辑以反映@ nerfologist在评论中的更正
小智 16
如果要将所有道具添加到状态并保留相同的名称,可以使用如下所示的简短形式.
constructor(props) {
super(props);
this.state = {
...props
}
//...
}
Run Code Online (Sandbox Code Playgroud)
Yon*_*Noh 13
您必须时初始化要小心state
来自props
于构造函数。即使props
更改为新的,状态也不会改变,因为 mount 再也不会发生了。因此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} />
);
}
}
Run Code Online (Sandbox Code Playgroud)
或者使用key
props 作为触发器来初始化:
class SecondComponent extends React.Component {
state = {
// initialize using props
};
}
Run Code Online (Sandbox Code Playgroud)
<SecondComponent key={something} ... />
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,如果something
更改,SecondComponent
则将重新挂载为新实例state
并由props
.
像这样在构造函数中设置状态数据
constructor(props) {
super(props);
this.state = {
productdatail: this.props.productdetailProps
};
}
Run Code Online (Sandbox Code Playgroud)
如果您componentDidMount()
通过 props在 side方法中设置,它将无法工作。