我正在尝试创建一个类似于此处的反应示例的过滤表:Thinking in React。我想要添加的是从总项目集中显示的项目数量。我的想法是将状态变量'numShowing'保留在顶级组件“Resources”中。我还在这个组件中创建了一个函数,使用setState()递增'numShowing'。然后,我将该函数传递给组件链,并在安装感兴趣的组件时调用它。这是一些伪代码(我删除了不必要的东西和对过滤组件的引用):
组件层次结构是:资源 - > 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(控制台输出验证函数)被称为正确的次数)。那么这样做的“正确”方法是什么?
答案 0 :(得分: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>
);
}
});