I've been working on a project which is coded with React. I have a component set that I implemented many components for my own requirements. Many of these act like a composite component. For example, TextBox component which has its own label, own error message mechanism and own input filter etc. Moreover, you know, components have props to manage sth.
Everytime to update my component view (render), I use componentWillReceiveProps
and I compare the props changes.
But everytime implementing the componentWillReceiveProps
method is so repulsive.
Is there any way to pass props from top to down without using componentWillReceiveProps
. I don't want to compare props changes manually. Is there any way to do it automatically.
When I change the props in parent, I'd like to update all views just changing the some prop values from top to down.
I'm not an react expert and performance is not my first purpose also!
One more thing that the answer is not use Redux
!
I'm waiting your creative approaches and helpful ideas.
I've been working on a project which is coded with React. I have a component set that I implemented many components for my own requirements. Many of these act like a composite component. For example, TextBox component which has its own label, own error message mechanism and own input filter etc. Moreover, you know, components have props to manage sth.
Everytime to update my component view (render), I use componentWillReceiveProps
and I compare the props changes.
But everytime implementing the componentWillReceiveProps
method is so repulsive.
Is there any way to pass props from top to down without using componentWillReceiveProps
. I don't want to compare props changes manually. Is there any way to do it automatically.
When I change the props in parent, I'd like to update all views just changing the some prop values from top to down.
I'm not an react expert and performance is not my first purpose also!
One more thing that the answer is not use Redux
!
I'm waiting your creative approaches and helpful ideas.
Share Improve this question edited Apr 12, 2017 at 14:28 Tugrul asked Apr 12, 2017 at 14:24 TugrulTugrul 1,8084 gold badges27 silver badges40 bronze badges 6 | Show 1 more comment3 Answers
Reset to default 11Without seeing the code for the particular thing you're working on, I may be missing something about what you're doing...
As others have commented, React will re-render your component if new props are provided, regardless of whether or not you implement componentWillReceiveProps
-- the only reason to implement it is to do some kind of specific comparison or set a state based on new prop values.
From the React docs (emphasis mine):
componentWillReceiveProps() is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare this.props and nextProps and perform state transitions using this.setState() in this method.
Note that React may call this method even if the props have not changed, so make sure to compare the current and next values if you only want to handle changes. This may occur when the parent component causes your component to re-render.
In other words, if you have a component like:
<TextBox title={"Foo"} content={"Bar"} />
That internally passes prop changes on to a couple of child components like:
class TextBox extends React.Component {
render() {
return (
<div className={'text-box'}>
<Title text={this.props.title} />
<Body text={this.props.content} />
</div>
);
}
}
Then each time new props are passed to <TextBox>
, <Title>
and <Body>
will also get re-rendered with their new text
props, and there's no reason to use componentWillReceiveProps
if you're just looking to update with prop changes. React will automatically see the changes and re-render. And React handles diffing and should fairly efficiently re-render only things that have changed.
However, if you have a separate state value that needs to be set in response to props, for example, if you wanted to show a "changed" state (or whatever) on the component if the new props are different, then you could implement componentWillReceiveProps
, like:
class TextBox extends React.Component {
componentWillReceiveProps(nextProps) {
if (this.props.content !== nextProps.content) {
this.setState({changed: true});
}
}
render() {
const changed = this.state.changed ? 'changed' : 'unchanged';
return (
<div className={`text-box ${changed}`}>
<Title text={this.props.title} />
<Body text={this.props.content} />
</div>
);
}
}
If you're trying to prevent re-render in cases where it's unnecessary for performance, do as Andrey suggests and use shouldComponentUpdate
: https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate
TLDR; unless you're setting component state from props, there's likely no need to run new props through componentWillReceiveProps
UPDATE Feb 2018: in a future release, React will be deprecating componentWillReceiveProps
in favor of the new getDerivedStateFromProps
, more info here: https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b
There are few suggestions:
- Don't copy props into state in
componentWillReceiveProps
- just render directly fromthis.props
- If your component need performance tweak (and only if there is problem with performance):
- start from using
shouldComponentUpdate
in generic form like advised here https://facebook.github.io/react/docs/shallow-compare.html - If generic approach doesn't work for you - write custom code
- start from using
The general approach, how to develop text-box-like components is to keep it stateless.Component renders props directly, and notifies parent component about changes, it don't cares about managing value.
Hope this will help
Please consider pureComponent
which by defualt implements the shouldComponentUpdate
inside which shallow equals is used for comparison between previous and next
try following codes:
class MyComponent extends PureComponent {...}
componentWillReceiveProps
if there's something specific you want to do in response to (potentially) updated props. – Oliver Charlesworth Commented Apr 12, 2017 at 14:26componentWillReceiveProps
to make your components reactive. I don't understand your question? – WilomGfx Commented Apr 12, 2017 at 14:27