ここでの反応の例に似たフィルター処理されたテーブルを作成しようとしています: 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 です (コンソール出力は関数を検証します)。正しい回数呼び出されています)。では、これを行う「正しい」方法は何でしょうか?