admin管理员组文章数量:1129438
In React, are there any real differences between these two implementations?
Some friends tell me that the FirstComponent
is the pattern, but I don't see why. The SecondComponent
seems simpler because the render is called only once.
First:
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;
Second:
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;
Update:
I changed setState()
to this.state = {}
(thanks joews), However, I still don't see the difference. Is one better than other?
In React, are there any real differences between these two implementations?
Some friends tell me that the FirstComponent
is the pattern, but I don't see why. The SecondComponent
seems simpler because the render is called only once.
First:
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;
Second:
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;
Update:
I changed setState()
to this.state = {}
(thanks joews), However, I still don't see the difference. Is one better than other?
9 Answers
Reset to default 235It should be noted that it is an anti-pattern to copy properties that never change to the state (just access .props directly in that case). If you have a state variable that will change eventually but starts with a value from .props, you don't even need a constructor call - these local variables are initialized after a call to the parent's constructor:
class FirstComponent extends React.Component {
state = {
x: this.props.initialX,
// You can even call functions and class methods:
y: this.someMethod(this.props.initialY),
};
}
This is a shorthand equivalent to the answer from @joews below. It seems to only work on more recent versions of es6 transpilers, I have had issues with it on some webpack setups. If this doesn't work for you, you can try adding the babel plugin babel-plugin-transform-class-properties
, or you can use the non-shorthand version by @joews below.
You don't need to call setState
in a Component's constructor
- it's idiomatic to set this.state
directly:
class FirstComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
x: props.initialX
};
}
// ...
}
See React docs - Adding Local State to a Class.
There is no advantage to the first method you describe. It will result in a second update immediately before mounting the component for the first time.
Update for React 16.3 alpha introduced static getDerivedStateFromProps(nextProps, prevState)
(docs) as a replacement for componentWillReceiveProps
.
getDerivedStateFromProps is invoked after a component is instantiated as well as when it receives new props. It should return an object to update state, or null to indicate that the new props do not require any state updates.
Note that if a parent component causes your component to re-render, this method will be called even if props have not changed. You may want to compare new and previous values if you only want to handle changes.
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
It is static, therefore it does not have direct access to this
(however it does have access to prevState
, which could store things normally attached to this
e.g. refs
)
edited to reflect @nerfologist's correction in comments
YOU HAVE TO BE CAREFUL when you initialize state
from props
in constructor. Even if props
changed to new one, the state wouldn't be changed because mount never happen again.
So getDerivedStateFromProps
exists for that.
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} />
);
}
}
Or use key
props as a trigger to initialize:
class SecondComponent extends React.Component {
state = {
// initialize using props
};
}
<SecondComponent key={something} ... />
In the code above, if something
changed, then SecondComponent
will re-mount as a new instance and state
will be initialized by props
.
You could use the short form like below if you want to add all props to state and retain the same names.
constructor(props) {
super(props);
this.state = {
...props
}
//...
}
set the state data inside constructor like this
constructor(props) {
super(props);
this.state = {
productdatail: this.props.productdetailProps
};
}
it will not going to work if u set in side componentDidMount()
method through props.
If you directly init state from props, it will shows warning in React 16.5 (5th September 2018)
you could use key
value to reset state when need, pass props to state it's not a good practice , because you have uncontrolled and controlled component in one place. Data should be in one place handled
read this
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key
You can use componentWillReceiveProps.
constructor(props) {
super(props);
this.state = {
productdatail: ''
};
}
componentWillReceiveProps(nextProps){
this.setState({ productdatail: nextProps.productdetailProps })
}
本文标签: javascriptReact component initialize state from propsStack Overflow
版权声明:本文标题:javascript - React component initialize state from props - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736731086a1949997.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
this.state = { isVisible: props.isVisible }
makes sense. Depends on how the app distributes UI state. – joews Commented Oct 15, 2016 at 20:00