Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getDerivedStateFromProps is not called

I use React 16.3.1 and next.js.
And I put getDerivedStateFromProps inside the class extending PureComponent.

Here is the code:

Header.js

import { PureComponent } from 'react'
...

export default class Header extends PureComponent {
  constructor (props) {
    super(props)

    this.colorAnimationProps = {
      animationDuration: '0.4s',
      animationFillMode: 'forwards'
    }

    this.colorAnimationStyle = {
      toColor: {
        animationName: 'toColor',
        ...this.colorAnimationProps
      },
      toTransparent: {
        animationName: 'toTransparent',
        ...this.colorAnimationProps
      }
    }

    this.state = {
      colorAnimation: {},
      headerModal: null
    }
  }

  componentDidMount () {
    if (this.props.isColor) {
      this.setState({colorAnimation: this.colorAnimationStyle.toColor})
    }
  }

  static getDerivedStateFromProps (nextProps, prevState) {
    console.log('should go here')
    if (nextProps.isColor) {
      return {colorAnimation: this.colorAnimationStyle.toColor}
    }
    return {colorAnimation: this.colorAnimationStyle.toTransparent}
  }

  render () {
    ...
  }
}

And here is the parent that modifies the prop:

index.js

import { PureComponent } from 'react'

...
import Header from '../components/Header'
import Layout from '../components/Layout'
import { withReduxSaga } from '../redux/store'

class Index extends PureComponent {
  constructor (props) {
    super(props)

    this.state = {
      isHeaderColor: false
    }
  }

  componentDidMount () {
    if (window.pageYOffset > 50) {
      this.setState({isHeaderColor: true})
    }

    window.addEventListener('scroll', (e) => {
      if (window.pageYOffset > 50) {
        this.setState({isHeaderColor: true})
      } else {
        this.setState({isHeaderColor: false})
      }
    })
  }

  render () {
    return (
      <Layout url={this.props.url}>
        <Header isColor={this.state.isHeaderColor} />
        ...
      </Layout>
    )
  }
}

export default withReduxSaga(Index)

My problem is: getDerivedStateFromProps is not called when the prop changes. At least, it should do console.log, but it doesn't.

Can anybody here help me?

like image 765
Rizki Sunaryo Avatar asked Apr 05 '18 13:04

Rizki Sunaryo


People also ask

What is getDerivedStateFromProps?

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing. This method exists for rare use cases where the state depends on changes in props over time.

Does setState call getDerivedStateFromProps?

Whenever the state is update via setState method, getDerivedStateFromProps is also executed even if the props have not changed.

Where is getDerivedStateFromProps used?

ReactJS – getDerivedStateFromProps() Method This method is called before the rendering or before any updation of the component. This method is majorly used to update the state, before the rendering of the component, which depends upon the props received by the component.

What is the alternative of ComponentWillMount?

ComponentWillMount() will go to be deprecated in the future releases of the React as per this issue. It is suggested to use ComponentDidMount() or useEffect hook as its alternative but you can still use ComponentWillMount() by calling it as UNSAFE_ComponentWillMount().


1 Answers

make sure you have the right versions of both react and react-dom in your package.json:

"react": "^16.3.1",
"react-dom": "^16.3.1"
like image 61
Miguel Salas Avatar answered Sep 22 '22 09:09

Miguel Salas