Modularize and abstract react component functionality

后端 未结 2 2045
予麋鹿
予麋鹿 2021-01-16 19:55

I have below a working component that allows for a checkbox all and checkboxes. It works perfectly. However I hate the idea that I\'m stuck carrying all of this code around

2条回答
  •  滥情空心
    2021-01-16 20:20

    The following example is in the right general direction I think, the general idea is to introduce a wrapper component for the related boxes, and then walk through the children in that component to tie them together.

    var CheckAll = React.createClass({
    render() {
      return 
    }
    });
    var Checkbox = React.createClass({
    render() {
      return 
    }
    });
    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 (
        
    {React.Children.map(this.props.children, this.enrichChild)}
    ) } }); var Test = React.createClass({ getInitialState: function () { return { boxes: { a: true, b: false, c: false, } } }, render: function () { return (
    this.setState({boxes})} >
    ) } }) React.render(, document.body)

    Here's a jsbin - https://jsbin.com/zomuxolevo/1/edit?js,output

    To allow for more flexibility with the children, you'd need to recursively walk them using something like this gist https://gist.github.com/dandelany/1ff06f4fa1f8d6f89c5e

    var RecursiveChildComponent = React.createClass({
      render() {
        return 
    {this.recursiveCloneChildren(this.props.children)}
    }, 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); }) } })

提交回复
热议问题