Render方法不会重新渲染构造函数中初始化的元素

时间:2018-03-19 05:55:43

标签: javascript reactjs constructor ecmascript-6 render

当我注意到受控表单元素的行为时,我是新手做出反应并正在进行实验。我有一个受控的输入元素,其值绑定到父组件的状态,其onChange处理程序从用户获取类型值并更新状态。所以每次,用户输入内容时,输入值都会反映出变化。这是理想的效果。在渲染函数中创建输入时,它很有用。但是,如果输入是通过在构造函数中设置的类变量初始化的,则相同的输入在状态更改时不会更新其值。唯一的区别是首先初始化输入元素。会导致这种行为的原因是什么? 任何帮助表示赞赏!

以下是导致错误行为的代码示例的示例:

class App extends React.Component {
  
  constructor(props){
    super(props);
    this.state = {
      val : '',
    }
    this.handleChange = this.handleChange.bind(this);
    this.input = (
    <input type="text" 
           onChange={this.handleChange } 
           value={this.state.val} />
    );
  }
  
  handleChange(e){
   this.setState({val:e.target.value});
  }
  render() {

    return (
      <div className="App">  
        { this.input ? this.input : null }                
      </div>
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

2 个答案:

答案 0 :(得分:3)

您已将输入存储(或缓存)到渲染之外的变量中。因此,当您的组件更新时,它只会一次又一次地呈现输入的缓存版本。

您需要将this.input定义为返回<input>的函数,如下所示:

this.input = () => (
    <input type="text" 
       onChange={this.handleChange } 
       value={this.state.val} />
);

并在渲染中调用this.input()。现在,输入将在每次渲染时更新。

但是,如果你想要的只是创建对输入的引用(this.input),我宁愿建议在渲染中使用the special prop ref

render() {
  <input type="text" 
    onChange={this.handleChange } 
    value={this.state.val}
    ref={input => (this.input = input)}  // the magic happens here
  />
}

这样做,您无需在构造函数中将this.input定义为函数。

答案 1 :(得分:3)

只有在装入之前,才会调用React组件的构造函数。 如果在构造函数中定义了一些变量,它将存储其值而不是引用,并且不会再次重新渲染。

参考react constructor

在道具/状态变化上调用的函数是

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • 渲染()
  • componentDidUpdate()

如果您想存储任何元素的引用,可以使用引用

render() {
  <input type="text" 
    onChange={this.handleChange } 
    value={this.state.val}
    ref={ ele => (this.input = ele)} 
  />
}

详细了解refs