为什么不能根据道具反应设置初始状态

fat*_*ahn 1 state ecmascript-6 reactjs es6-class react-fiber

我有一个es6 react组件,我希望状态的初始值取决于传递的prop的初始值,但其值始终为false:

AttachStateToProps组件

<AttachStateToProps VALUE=false />
Run Code Online (Sandbox Code Playgroud)

AttachStateToProps组件:

class AttachStateToProps extends React.Component {
  state = {
    stateValue: this.props.VALUE,
  }
  render() {
    console.log('Value of Prop - ', this.props.VALUE)
    console.log('Value of State - ', this.state.stateValue)

  return null
  }
}
Run Code Online (Sandbox Code Playgroud)

每次更改prop VALUE的值时,我得到:

`Value of Prop - false` // this changes whenever I change prop value in 
   <AttachStateToProps />
Run Code Online (Sandbox Code Playgroud)

`Value of State - false` // this does not change accordingly.
Run Code Online (Sandbox Code Playgroud)

认为这可能与state / setState异步且较旧有关,getinitialState但我不知道为什么。

Ori*_*ori 5

当prop更改时,从构造器中的prop初始化状态或将其初始化为类属性将不会更新状态。但是,react确实会检测到道具更改,并重新释放组件。

例:

class AttachStateToProps extends React.Component {
  state = {
    stateValue: this.props.VALUE,
  }
  render() {
    console.log('Value of Prop - ', this.props.VALUE)
    console.log('Value of State - ', this.state.stateValue)

  return null
  }
}

const renderWithVal = (val) => ReactDOM.render(
  <AttachStateToProps VALUE={val} />,
  demo
);

renderWithVal(5);
renderWithVal(15);
renderWithVal(115);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="demo"></div>
Run Code Online (Sandbox Code Playgroud)

要在prop更改时更新状态,您需要使用组件的生命周期方法

使用React ^ 16.3,您可以使用static getDerivedStateFromProps()方法来更新道具的状态(以及对其进行初始化):

static getDerivedStateFromProps(nextProps) {    
  return {
    stateValue: nextProps.VALUE,
  }
}
Run Code Online (Sandbox Code Playgroud)

static getDerivedStateFromProps(nextProps) {    
  return {
    stateValue: nextProps.VALUE,
  }
}
Run Code Online (Sandbox Code Playgroud)
class AttachStateToProps extends React.Component {
  state = {};

  static getDerivedStateFromProps(nextProps) {    
    return {
      stateValue: nextProps.VALUE,
    }
  }
      
  render() {
    console.log('Value of Prop - ', this.props.VALUE)
    console.log('Value of State - ', this.state.stateValue)

  return null
  }
}

const renderWithVal = (val) => ReactDOM.render(
  <AttachStateToProps VALUE={val} />,
  demo
);

renderWithVal(5);
renderWithVal(15);
renderWithVal(115);
Run Code Online (Sandbox Code Playgroud)

在16.3之前的React版本中,您可以使用componentWillReceiveProps()

注意:componentWillReceiveProps已过时,但将一直使用到版本17。

componentWillReceiveProps(nextProps, prevState) {
  this.setState({
    stateValue: nextProps.VALUE,
  })
}
Run Code Online (Sandbox Code Playgroud)