1

我正在尝试创建一个类似于此处的反应示例的过滤表:Thinking in React。我想添加的是在总项目集中显示多少项目的计数。我的想法是在顶级组件“资源”中保留状态变量“numShowing”。我还在这个组件中创建了一个函数来使用 setState() 增加“numShowing”。然后,我将该函数沿组件链传递,并在安装感兴趣的组件时调用它。这是一些伪代码(我删除了不必要的东西和对过滤组件的引用):

组件层次结构是:Resources -> ResourcesTable -> ResourcesTableEntry。

var Resources = React.createClass({
  getInitialState: function() {
    return {
      numShowing: 0
    };
  },
  incrementShowing: function() {
    console.log('increment from: ' + this.state.numShowing);
    this.setState({numShowing: this.state.numShowing + 1});
  },
  render: function() {
      <div>
        <ResourcesTable resources={this.state.resources} incrementShowing={this.incrementShowing} />
      </div>
    );
  }
});

var ResourcesTable = React.createClass({
  createEntry: function(resource) {
      if (/* filtered out */) {
        return;
      } else {
        return(<ResourcesTableEntry key={resource.id} resource={resource} incrementShowing={this.props.incrementShowing} />);
      }
  },
  render: function() {
    return (
      <table>
          <tbody>
            { this.props.resources.map(this.createEntry) }
          </tbody>
      </table>
    );
  }
});

var ResourcesTableEntry = React.createClass({
  componentDidMount: function() {
    this.props.incrementShowing();
  },
  render: function() {
    return (
      <tr>
        /* output props here */
      </tr>
    );
  }
});

我还尝试从 ResourcesTable.createEntry 函数递增。在这两种情况下,numShowing 只会设置为 1。我认为这是因为 setState 是异步的或非原子的,因此每次调用 incrementShowing() 时 numShowing 的当前状态为 0(控制台输出验证函数被调用的次数正确)。那么这样做的“正确”方法是什么?

4

1 回答 1

0

这里的问题是您不想在渲染方法中更新状态,因为它是一种反模式。该问题可以通过将过滤移至将拥有的组件来解决numShowing,即Resources。这将消除对ResourceTable组件的需求。

var Resources = React.createClass({
  render: function() {
    numShowing = 0;
    filteredResources = this.state.resources.map(function(resource){
      if (/* filtered out */) {
        return;
      }
      numShowing++; 
      return(<ResourcesTableEntry key={resource.id} resource={resource} />);
    }.bind(this));
    return(
      <div>
        <span> Number of results: {numShowing} </span>
        {filteredResources}
      </div>
    );
  }
});
于 2015-03-12T01:57:15.997 回答