if props is not in state, and props is identification marks for certain methods,
componentWillReceiveProps(nextProps) {
if (nextProps.flag !== this.props.flag && nextProps.flag) {
this.doSomething()
}
}
what should i do after used getDerivedStateFromProps
flag is not in state, so i can not used componentDidUpdate to do this.
if getDerivedStateFromProps+ componentDidUpdate instead of componentWillReceiveProps is the only way
flag is not in state, so i can not used componentDidUpdate to do this.
You can:
componentDidUpdate(prevProps) {
if (prevProps.flag !== this.props.flag && nextProps.flag) {
this.doSomething();
}
}
componentDidUpdate accepts both prevProps and prevState as arguments, as documented.
You don't need getDerivedStateFromProps for this.
@gaearon flag is only identification marks,Render action will not be triggered, componentDidUpdate executed???
React always calls componentDidUpdate unless you bailed out with shouldComponentUpdate.
@gaearon you may not understand what i mean, flag???
import React, { PureComponent } from 'react';
import PropType from 'prop-types';
export default class ExamplePage extends PureComponent {
componentDidUpdate(prevProps) {
if (prevProps.flag && this.props.flag !== prevProps.flag) {
this.handleDoSomething();
}
}
handleDoSomething = () => {
console.log('handleDoSomething');
};
render() {
const { title } = this.props;
return (
<div>
<p>{title}</p>
</div>
);
}
}
ExamplePage.propTypes = {
title: PropType.string.isRequired,
flag: PropType.bool.isRequired,
};
I don’t understand your problem. Does this code not work?
you can try, only change flag in parent component then see Console
Sorry. Please provide an example I can run — I don't understand your problem.
Parent
import React from 'react';
import ExamplePage from './ExamplePage';
/* eslint-disable react/prefer-stateless-function */
export class NewPage extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
flag: false,
title: 'Hello',
};
}
handleClick = () => this.setState({ flag: true });
render() {
const { title, flag } = this.state;
return (
<div>
<p onClick={this.handleClick}>Btn</p>
<ExamplePage flag={flag} title={title} />
</div>
);
}
}
export default NewPage;
ExamplePage
import React, { PureComponent } from 'react';
import PropType from 'prop-types';
export default class ExamplePage extends PureComponent {
componentDidUpdate(prevProps) {
if (prevProps.flag && this.props.flag !== prevProps.flag) {
this.handleDoSomething();
}
}
handleDoSomething = () => {
console.log('handleDoSomething');
};
render() {
const { title } = this.props;
return (
<div>
<p>{title}</p>
</div>
);
}
}
ExamplePage.propTypes = {
title: PropType.string.isRequired,
flag: PropType.bool.isRequired,
};
click Btn change flag, title not change, so componentDidUpdate executed?
in old version
componentWillReceiveProps(nextProps) {
if (nextProps.flag !== this.props.flag && nextProps.flag) {
this.doSomething()
}
}
Your code displays the message when the flag changes from true to false.
componentDidUpdate(prevProps) {
if (prevProps.flag && this.props.flag !== prevProps.flag) {
this.handleDoSomething();
}
But you are changing it from false to true.
handleClick = () => this.setState({ flag: true });
This is why you don’t see the message.
Did you mean to write this instead?
componentDidUpdate(prevProps) {
if (this.props.flag && this.props.flag !== prevProps.flag) {
this.handleDoSomething();
}
I think the root of your misunderstanding is that in componentWillReceiveProps the argument is new props, and this.props are old props. But in componentDidUpdate the update has already happened so the argument is old props, and this.props are the new props.
@Statfine , may be your problem is:
_Why the child component rerender when parent's state: flag changes, although flag not used in child's render ?_
If so, then the reason is:
when parent rerender, the process comes to child's shouldComponentUpdate, after the internal shallowEqual it gets true, so rerender, different from Vue's dependencies collection (or mobx?)
That's why we need shouldComponentUpdate to optimize our component.
Thanks, It's my understanding mistake
@AliasT Thanks,you are right
Most helpful comment
Your code displays the message when the flag changes from true to false.
But you are changing it from false to true.
This is why you don’t see the message.
Did you mean to write this instead?
I think the root of your misunderstanding is that in
componentWillReceivePropsthe argument is new props, andthis.propsare old props. But incomponentDidUpdatethe update has already happened so the argument is old props, andthis.propsare the new props.