我认为以下示例是正确的总体方向,总体思路是为相关框引入一个包装器组件,然后遍历该组件中的子组件将它们连接在一起。
var CheckAll = React.createClass({
render() {
return <input type="checkbox" {...this.props} />
}
});
var Checkbox = React.createClass({
render() {
return <input type="checkbox" {...this.props} />
}
});
var CheckboxGroup = React.createClass({
setAll(to) {
var result = {};
Object.keys(this.props.boxes).forEach(k => result[k] = to)
this.props.onChange(result);
},
setOne(name, to) {
var result = {};
Object.keys(this.props.boxes).forEach(k => result[k] = this.props.boxes[k])
result[name] = to;
this.props.onChange(result);
},
enrichChild(child) {
var boxes = this.props.boxes;
var all = Object.keys(boxes).every(k => boxes[k]);
if (child.type == CheckAll) {
return React.cloneElement(child, { checked: all,
onChange: () => this.setAll(!all)
});
} else if (child.type == Checkbox) {
var name = child.props.name;
return React.cloneElement(child, { checked: !!boxes[name],
onChange: ({target}) => this.setOne(name, target.checked)
});
} else {
return child;
}
},
render() {
return (
<div>
{React.Children.map(this.props.children, this.enrichChild)}
</div>
)
}
});
var Test = React.createClass({
getInitialState: function () {
return {
boxes: {
a: true,
b: false,
c: false,
}
}
},
render: function () {
return (
<div>
<CheckboxGroup
boxes={this.state.boxes}
onChange={boxes => this.setState({boxes})}
>
<CheckAll />
<Checkbox name="a" />
<Checkbox name="b" />
<Checkbox name="c" />
</CheckboxGroup>
</div>
)
}
})
React.render(<Test/>, document.body)
这是一个 jsbin -https://jsbin.com/zomuxolevo/1/edit?js,输出 https://jsbin.com/zomuxolevo/1/edit?js,output
为了让孩子们更加灵活,您需要使用类似这样的要点递归地行走他们https://gist.github.com/dandelany/1ff06f4fa1f8d6f89c5e https://gist.github.com/dandelany/1ff06f4fa1f8d6f89c5e
var RecursiveChildComponent = React.createClass({
render() {
return <div>
{this.recursiveCloneChildren(this.props.children)}
</div>
},
recursiveCloneChildren(children) {
return React.Children.map(children, child => {
if(!_.isObject(child)) return child;
var childProps = {someNew: "propToAdd"};
childProps.children = this.recursiveCloneChildren(child.props.children);
return React.cloneElement(child, childProps);
})
}
})