复合组件:如何在react中引用单击的子元素?

时间:2019-06-16 17:03:59

标签: javascript reactjs

我有以下React组件。

function Parent({ children }) {
  return <div>{children}</div>;
}

function MyChild({ children }) {
  return <div>{children}</div>;
}

function App() {
  return (
    <div>
      <Parent>
        <MyChild>text</MyChild>
        <MyChild>text</MyChild>
      </Parent>
    </div>
  );
}

我想捕获在Parent组件中单击的MyChild元素并将一个类附加到该元素。如何在不更改此实现的情况下做到这一点?

3 个答案:

答案 0 :(得分:1)

您可以使用React.cloneElement。例如

function Parent({ children }) {

  return <div>
    {React.Children.map(
      React.Children.toArray(children),
        (child) => {
          React.cloneElement(
            child,
            { onClick: () => { /** Do stuf */ } }
          )
        }
      )}
    </div>
}

答案 1 :(得分:1)

您需要为每个Parent子代弹出属性:

function Parent({ children }) {
  const ejectedChildren = Children.map(children, child =>
    cloneElement(child, { onClick: () => console.log('Clicked') })
  );

  return <>{ejectedChildren}</>;
}

React.Children.map使用React.cloneElement将每个孩子映射到具有其他onClick属性的新元素。

React.Children.map接收组件children和一个mapping函数。

React.cloneElement接收一个组件和其他属性,然后使用浅层合并的新道具创建一个新组件。

演示:

Edit Q-56620933-SO

另一个example injecting to all tree

答案 2 :(得分:0)

您可以执行以下操作:

function Parent({ children }) {

  return <div>
    {children}
  </div>
}

function MyChild({ children ,handleClick}) {
  return <div onClick={handleClick}>{children}</div>
}

function App() {
  return <div>
    <Parent>
      <MyChild handleClick={() => console.log("hello1")}>text</MyChild>
      <MyChild  handleClick={() => console.log("hello2")}>text</MyChild>
    </Parent>
  </div>
}

这是演示:https://codesandbox.io/s/clever-rubin-gxjrt。 虽然不建议这样做。我建议您为此使用上下文。