How to create React's new static function getDerivedStateFromProps as a lifecycle method using an HoC in the recompose library?

theJuls picture theJuls · Apr 17, 2018 · Viewed 7.2k times · Source

Recently it has come out that soon React will be deprecating componentWillReceiveProps and in it's place is the new static function getDerivedStateFromProps. See more here

I am currently migrating my apps to this new API, but am having an issue withgetDerivedStateFromProps, due to the fact that I am using the recompose library for higher order components. We make the use of componentWillReceive props through the library's lifecycle object.

So before moving to the new API, I had this:

export function someHoC () {
  return compose(
    lifecycle({
      componentWillReceiveProps (nextProps) {
        const { fetch } = nextProps
          if (shouldFetch(this.props, nextProps)) {
             fetch()
          }
      }
    })
  )
}

This has now changed to the following:

export function someHoC () {
  return compose(
    lifecycle({
      getDerivedStateFromProps (nextProps) {
          const { fetch } = nextProps
          if (shouldFetch(this.props, nextProps)) {
             fetch()
          }
      }
    })
  )
}

However, getDerivedStateFromProps needs to be static, so I am getting the warning regarding that and don't know how to handle it.

warning.js?7f205b4:33 Warning: lifecycle(MyComponent): getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.

What can I do to pass it in as a static lifecycle method into my component?

Answer

Sauce picture Sauce · Apr 19, 2018

If you want to use getDerivedStateFromProps you need to declare it as a static method:

static getDerivedStateFromProps() {...}

Obviously, this makes getDerivedStateFromProps static, which means you can't call it the same as you could call componentWillReceiveProps.

If a static method doesn't work for you, you can move your logic into componentDidUpdate to silence the warning. However this can cause an additional render if you call setState() from this method. Depending on what happens when you resolve your fetch(), this may work for you.

You can also replace componentWillReceiveProps with UNSAFE_componentWillReceiveProps (docs), which will work the same way. However, due to the upcoming async rendering feature, this could cause some issues.