我可能会将您的状态设置为包含一个对象数组(代表您的复选框)和一个代表您的过滤器的字符串。每个复选框对象将包含两个属性:标签的文本和复选框的值。
对于您的初始状态,您希望该数组为空,然后在componentDidMount
在生命周期中,您将执行 API 调用并将状态设置为包含您收到的信息。
constructor(props) {
super(props);
this.state = {
checkboxes: [],
filter: 'ALL'
};
//each checkbox would take the form of {label: 'some label', checked: true}
}
componentDidMount() {
getData(response => { //some API call
this.setState({
checkboxes: response.body
});
});
}
为了让您的组件呈现这些复选框,它需要了解状态下的复选框对象与实际 DOM 元素的关系。您可以创建一个辅助函数来利用.map
去做这个。您还可以利用.filter
将过滤器应用于您所在州的每个对象,并删除与过滤器不匹配的对象。
function renderCheckboxes() {
const {checkboxes, filter} = this.state;
return checkboxes
.filter(checkbox =>
filter === 'ALL' ||
filter === 'CHECKED' && checkbox.checked ||
filter === 'UNCHECKED' && !checkbox.checked
)
.map((checkbox, index) =>
<div>
<label>
<input
type="checkbox"
checked={checkbox.checked}
onChange={toggleCheckbox.bind(this, index)}
/>
{checkbox.label}
</label>
</div>
);
}
请注意每个复选框如何将 onChange 属性映射到某个函数?您需要将其提供给使用以下方式呈现的每个复选框checked
属性,因为您将创建一个受控组件 https://facebook.github.io/react/docs/forms.html#controlled-components,并且您的状态将控制是否检查每个单独的组件。你的toggleCheckbox
函数可能看起来像这样:
function toggleCheckbox(index) {
const {checkboxes} = this.state;
checkboxes[index].checked = !checkboxes[index].checked;
this.setState({
checkboxes
});
}
创建一个将过滤器设置为不同字符串的函数也可能很有用:
function updateFilter(filter) {
this.setState({
filter
});
}
最后,您可以在您的应用程序中使用这些功能render
函数来显示您的复选框以及更新过滤器状态的链接(我还添加了一些不间断空格来分隔每个过滤器链接):
render() {
return (
<div>
{renderCheckboxes.call(this)}
<div>
<h4>Filters ({this.state.filter})</h4>
<a href="#" onClick={updateFilter.bind(this, 'ALL')}>ALL</a>
|
<a href="#" onClick={updateFilter.bind(this, 'CHECKED')}>CHECKED</a>
|
<a href="#" onClick={updateFilter.bind(this, 'UNCHECKED')}>UNCHECKED</a>
</div>
</div>
);
}
以下是此工作的示例 - 减去 API 调用:
https://jsbin.com/bageyudaqe/edit?js,输出 https://jsbin.com/bageyudaqe/edit?js,output
希望这可以帮助!