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

时间:2018-05-18 04:14:58

标签: reactjs ecmascript-6 state es6-class react-fiber

我有一个es6 react组件,我希望状态的初始值依赖于传递的prop的值,但它的值总是为false:

AttachStateToProps组件

<AttachStateToProps VALUE=false />

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
  }
}

每次改变道具价值时,我都会得到:

`Value of Prop - false` // this changes whenever I change prop value in 
   <AttachStateToProps />

`Value of State - false` // this does not change accordingly.

我认为it could be something to do with state/setState being async及更早getinitialState,但我不知道为什么。

2 个答案:

答案 0 :(得分:5)

从构造函数中的props初始化状态,或作为类属性,在prop更改时不会更新状态。但是,react会检测到prop变化,并重新渲染组件。

示例:

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);
<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>

要更改道具更改时的状态,您需要使用组件的lifecycle method

使用React ^ 16.3,您可以使用静态getDerivedStateFromProps()方法从props更新状态(并初始化它):

static getDerivedStateFromProps(nextProps) {    
  return {
    stateValue: nextProps.VALUE,
  }
}

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);
<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>

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

注意:不推荐使用componentWillReceiveProps,但是直到第17版才能使用。

componentWillReceiveProps(nextProps, prevState) {
  this.setState({
    stateValue: nextProps.VALUE,
  })
}

答案 1 :(得分:1)

没有构造函数中的super(props),它将无法工作。

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