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

Adding Event Handlers/Props to inner markup in React

本文关键字:事件处理 添加 程序 道具 React 内部      更新时间:2023-09-26

我试图在React中创建一个可重复的组件。目标是,它可以给定任何有效的React组件group,并接受任何callbacks列表,并将这些回调应用于group元素。下面是我的工作原理,我将解释它与我想要做的有什么不同。链接到codepen:

http://codepen.io/cirsca/pen/vKqzjZ?编辑= 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>
    }
}

我的dummy Group组件是:

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,我没有放入我的代码中)。

我觉得我在这里过于复杂的事情,但我不确定去哪里找,或者谷歌什么开始。

可以递归克隆子元素并向下传递props

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>
)