在React中将事件处理程序/道具添加到内部标记

时间:2016-08-25 19:56:21

标签: javascript reactjs

我正在尝试在React中创建一个可重复的组件。目标是可以为任何group提供有效的React组件并获取callbacks的任何列表,并将这些回调应用于group元素。以下是我有点工作的内容,我将解释它与我之后想要做的有什么不同。链接到codepen:

http://codepen.io/cirsca/pen/vKqzjZ?editors=0011

我的包装组件:

class App extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            callbacks: {
                onClick: (e) => console.log('I was clicked!')
            }
        }
    }

    render(){
        return <div>
            <Repeatable 
                group={<Group />}
                {...this.state.callbacks}
            />
        </div>
    }
}

我的中继器组件:

class Repeatable extends React.Component {
    constructor(props){
        super(props)
        const {group, ...callbacks} = this.props
        this.state = {
            group: group || <div>This is awesome!</div>,
            list: [group],
            callbacks
        }
    }

    addGroup = () => this.setState({
        list: [
            ...this.state.list,
            this.state.group
        ]
    });

    render(){
        return <div id={this.props.cssID || 'react_repeatable'}>
            <button onClick={this.addGroup}>Add Group</button>
            <div className="repeated__list">
                {this.state.list.map(el => {
                    return React.cloneElement(el, {...this.state.callbacks})
                })}
            </div>
        </div>
    }
}

我的虚拟组件是:

const Group = ({className, ...callbacks}) => (
    <div className={className || 'repetable__block'} {...callbacks}>
        <p>Here is a repeatable group!</p>
    </div>
)

只要我想将回调附加到Group组件中的根元素,这就可以工作。我想要的是一种方式,我的callbacks可以针对嵌套的p标记,或者我不能对每个基础组件和操作进行十亿次onClick={callbacks.onClick ? ....}检查(以防万一)一个新的onAction出来了,我没有把它放到我的代码中)。

我觉得我在这里过于复杂,但我不确定在哪里可以找到它或谷歌开始。非常感谢任何和所有帮助。

1 个答案:

答案 0 :(得分:1)

您可以递归克隆子项并将道具传递下来

const recursiveCloneChildren = (children, props) => {
  return React.Children.map(children, child => {
    let childProps = {};
    if (React.isValidElement(child)) {
      childProps = props;
    }
    childProps.children = this.recursiveCloneChildren(child.props.children);
    return React.cloneElement(child, childProps);
  })
}

const Group = ({className, children, ...callbacks}) => (
  <div className={className || 'repetable__block'} {...callbacks}>
    {recursiveCloneChildren(children, callbacks)}
  </div>
)