【问题标题】:react parent not re-rendering child despite state change尽管状态发生变化,但反应父母不重新渲染孩子
【发布时间】:2016-07-07 09:36:20
【问题描述】:

我有一个 DatePicker 父组件,它有一个子 SearchBar 组件。 SearchBar 是一个有 onChange 的输入,它连接到 DatePicker 的 handleSearchChange。由于 DatePicker 向下传递其 currentDateObj 状态,SearchBar 将使用插入的当前日期进行初始化。但是,SearchBar 的输入应该从用户输入改变,因为它的 onChange 会改变 DatePicker 的状态,这反过来又会改变 SearchBar 的输入,但即使使用我的 console.logs,我也看不到 SearchBar 被重新渲染并且输入不断重置自己到初始日期(今天),而不是显示对用户输入的任何更改。

//DatePicker
    var DatePicker = React.createClass({
          getInitialState: function () {
            var today = new Date();
            return {currentDateObj: today, searchInput: undefined};
          },
          handleSearchChange: function (e) {
            var inputString = e.target.value.toString();
            var inputRegex = /^\d{2}[/]\d{2}[/]\d{4}$/;
            if (inputRegex.test(inputString)) {
              var year = e.target.value[6]+e.target.value[7]+e.target.value[8]+e.target.value[9];
              var month = e.target.value[0]+e.target.value[1];
              var day = e.target.value[3]+e.target.value[4];
              var currentDateObj = new Date(year, month, day);
              this.setState({currentDateObj:currentDateObj });
            } else {
              this.setState({searchInput: inputString});
            }
          },
          render: function () {
            var datePickerComponent = this;
            var dateNextYearObj = new Date();
            var searchDateObj = this.state.searchInput === undefined ? this.state.currentDateObj : this.state.searchInput;
            console.log('hit datepick render');
            console.log(this.state.searchInput);
            dateNextYearObj.setFullYear(this.state.currentDateObj.getFullYear() + 1);
            return(
              <div>
                <SearchBar currentDateObj={searchDateObj} handleSearchChange={this.handleSearchChange}/>
              </div>
            );
          }
        });

//搜索栏

var SearchBar = React.createClass({
  getInitialState: function () {
    console.log('hit searchbar render')
    var currentDateObj = this.props.currentDateObj;
    if(typeof (currentDateObj.getMonth) === "function"){

      var currentDate = currentDateObj.getDate().toString();
      if (currentDate.length === 1) {currentDate = "0" + currentDate;}

      var currentMonth = currentDateObj.getMonth().toString();
      if (currentMonth.length === 1) {currentMonth = "0" + currentMonth;}

      var currentYear = currentDateObj.getFullYear().toString();

      var formattedCurrentDate = currentMonth + "/" + currentDate + "/" + currentYear;
      return {currentDateObj: formattedCurrentDate};
    } else {

      return {currentDateObj: currentDateObj};
    }
  },
  render: function () {
    return (
      <div>
        <input type="text" onChange={this.props.handleSearchChange} value={this.state.currentDateObj}/>
      </div>
    );
  }
});

【问题讨论】:

    标签: reactjs components parent-child render state


    【解决方案1】:

    修改后的答案

    getIntialState 方法仅在首次创建组件时调用一次,因此在后续渲染中将无用。

    您可能希望将格式化逻辑粘贴到其他地方,例如渲染函数或更方便的生命周期方法,例如 componentWillReceiveProps,这就是我的做法。让我知道这是否有帮助,祝你好运。


    资源


    旧答案:

    由于Autobind by Default而不再相关

    在传递处理程序时,您可能会丢失 this 绑定。试试这个:

    <SearchBar currentDateObj={searchDateObj} handleSearchChange={this.handleSearchChange.bind(this)}/>
    

    查看所有可以在this blog 中通过Igor Smirnov 管理绑定的酷方法。我使用 Babel 转译我的代码并使用 stage-0 预设,我可以简单地在我的类处理程序方法中使用粗箭头函数,因此我不必担心 this

    【讨论】:

    • React 说它已经在为我做竞标“警告:bind():您正在将组件方法绑定到组件。React 以高性能的方式自动为您执行此操作,因此您可以安全地删除此调用。请参阅 DatePicker"
    • 我看到您在 getIntialState 中使用了道具,该道具仅在首次创建组件时调用一次。您可能希望将格式化逻辑粘贴到其他地方。
    【解决方案2】:

    尝试将关键字 this 绑定到您的 handleSearchChange 函数。

    <SearchBar currentDateObj={searchDateObj} handleSearchChange={this.handleSearchChange.bind(this)}/>
    <input type="text" onChange={this.props.handleSearchChange.bind(this)} value={this.state.currentDateObj}/>    
    

    如果您遇到类似“无法读取属性 'setState' of null 的错误,将 this 绑定到您的函数应该可以解决该错误。

    【讨论】:

    • 这是我得到的响应 "warning.js:45Warning: bind(): You are binding a component method to the component. React 以高性能的方式自动为您执行此操作,因此您可以安全地删除此调用。请参阅 DatePicker"
    • "警告:bind():React 组件方法只能绑定到组件实例。参见 DatePicker"
    • 嗯。我建议在您的 handleSearchChange 函数中记录 this 控制台。如果控制台日志显示 this 指的是窗口对象或 null,那么我的猜测是您的 this 绑定正在丢失。如果控制台日志显示 this 指代您的 DatePicker 组件,那么我不确定发生了什么。
    猜你喜欢
    • 2016-12-18
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2019-11-19
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多