0

I have a React function component, where I get another component in props. Something like this:

function ChildComponent({cmp}) {
    // Here onClick handlers should be added [for example:
    // () => console.log("clicked")] to all
    // elements in cmp of class .clickable

    return ...
}

function ParentComponent() {
    return (
        <ChildComponent cmp={<div><button>Non-clickable</button><button className="clickable">Clickable</button></div>} />
    )
}

So how to add event handlers dynamically to elements with class clickable in the cmp props variable in the ChildComponent? Thank you in advance for your help.

2
  • Where do you want your onClick handler in, your ParentComponent or your ChildComponent? Commented Nov 11, 2019 at 3:03
  • In the ChildComponent Commented Nov 11, 2019 at 3:56

1 Answer 1

1

This uses Children API that allows you to modify children's props based on its current props. The ChildComponent will first loop through its current children, look for clickable className props and add onClick handler to its props.

The recursion loop allows nested children to work too.

function ChildComponent({ cmp }) {
  const handleOnClick = () => {
    alert("Clicked");
  };

  const childrenMap = (child) => {
    if (child.props) {
      const newProps = Object.assign({}, child.props);
      const { children, className } = newProps;
      if (className && className.split(' ').some(cn => cn === 'clickable')) {
        newProps.onClick = handleOnClick;
      }
      if (children) {
        newProps.children = Children.map(children, childrenMap);
      }
      return cloneElement(child, newProps);
    }
    return child;
  }

  return Children.map(cmp, childrenMap);
}

function ParentComponent() {
  return (
    <ChildComponent
      cmp={(
        <div>
          <button>Non-clickable</button>
          <div>
            <div>
              <button className="clickable">Clickable</button>
            </div>
          </div>
          <button className="clickable">Clickable</button>
        </div>
      )}
    />
  );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.