Execute a function after Props change
Asked Answered
B

2

17

I want to execute a function in Child Component after props gets changed in the Parent Component without having to manage an extra state in Child/Parent.

<ParentCompoenent 
  myCallback={() => {}}
  myList={['a','b','c']}
/>

ChildComponent.js

componentWillReceiveProps(nextProps) {
  console.log(this.props.myList, '==', nextProps.myList);  // Outputs ['a','b','c'] == ['a','b','c']
}

When I'm trying to console the nextProps in componentWillReceiveProps its giving the same result every time even after the props have been changed.

Beltran answered 8/2, 2021 at 7:40 Comment(0)
O
23

you have to use componentDidUpdate in class components and useEffect in Function components...

componentDidUpdate like this:

    componentDidUpdate(prevProps, prevState) {
            if (prevProps.something !== this.props.something) {
                   console.log('something prop has changed.')
            }
    }

componentDidUpdate will run console.log every time the new prop is different from prevProps.

and in useEffect you just add the props to its dependency:

useEffect(()=>{
    console.log('something prop has changed.')
},[props.something]);

useEffect will call that function every time the value of that prop changes.

Oakes answered 8/2, 2021 at 8:29 Comment(1)
You may have to use did mount, did update and will unmount to properly implement the useEffect in a class component. Did update is not run on mount only on re renders.Archives
A
1

Not sure what your question has to do with react redux but here is your code not showing the behavior you describe (there is nothing wrong with the code you posted in your question). Please provide a minimum reproducible example of your problem.

class ChildComponent extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.log(this.props.myList, '==', nextProps.myList); // Outputs ['a','b','c'] == ['a','b','c']
  }
  render() {
    return (
      <pre>
        {JSON.stringify(this.props.myList, undefined, 2)}
      </pre>
    );
  }
}
const ParentCompoenent = () => {
  const [myList, setMyList] = React.useState([1, 2, 3]);
  const changeList = React.useCallback(
    () => setMyList((list) => list.concat(list.length + 1)),
    []
  );
  return (
    <div>
      <button onClick={changeList}>Change list</button>
      <ChildComponent myList={myList} />
    </div>
  );
};

ReactDOM.render(
  <ParentCompoenent />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

You should avoid using componentWillReceiveProps and maybe make the component a functional component and use the useEffect hook or use did mount, did update and possibly will unmount for class components.

Archives answered 8/2, 2021 at 8:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.