Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React js lifecycle methods not firing on wrapped component

Here is a component:

export default class MyComponent extends React.Component {
  componentWillReceiveProps(newProps) {
    console.log('RECEIVED PROPS');
  }

  render() {
    return <div>{this.props.foo}</div>
  }
}

Here is a wrapper/higher-order-component:

  const withSomething = (ComponentToWrap) => {
    render() {
      return <ComponentToWrap {...this.props} />
    }
  }

Here is a functional component that wraps MyComponent in withSomething:

export default function WrappedComponent(props) {
    const Component = withSomething(MyComponent);
    return <Component ... some props ... />
}

Result: props-related lifecycle functions (such as componentWillReceiveProps) in MyComponent never fire, even when I update the props.

What is up with this? Do props-based lifecycle methods not work on wrapped components?

like image 376
Peter Hollingsworth Avatar asked May 23 '17 18:05

Peter Hollingsworth


People also ask

Will any lifecycle methods be triggered if the props of a component change?

Any changes on the props object will also trigger the lifecycle and is almost identical to the state change with one additional method being called. componentWillReceiveProps is only called when the props have changed and when this is not an initial rendering.

Which lifecycle method will avoid re rendering of a component?

Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

Are React lifecycle methods deprecated?

There are a few life cycle methods that have been deprecated and renamed in React 17. We don't need to use these anymore— getDerivedStateFromProps and getSnapshotBeforeUpdate essentially replaced them.

What triggers componentDidUpdate?

The componentDidUpdate event is triggered whenever there is a state or props update. ComponentDidUpdate() has access to three properties, two of which are most often used more than the third. These are prevProps, prevState and lastly, snapshot, which is used less often.


1 Answers

The problem is that since the line that creates the wrapped component is contained in the functional component, it basically creates a new component every time the functional component renders.

This line ends up being included in WrappedComponent's render method:

const Component = withSomething(MyComponent);

...which means Component gets overwritten at every render.

Another clue is to put a componentDidMount() into MyComponent -- it'll fire every time the props update.

Solution is to create the wrapped component somewhere OUTSIDE the functional component, or outside the render method if you are using a regular class component.

like image 85
Peter Hollingsworth Avatar answered Oct 21 '22 07:10

Peter Hollingsworth