React.cloneElement 克隆已经克隆的元素以添加新的道具

onu*_*rhb 5 reactjs

我有TestWrapper一个克隆组件element,应该使背景变成蓝色。Test也在做同样的事情,但是设置了color. 我期望渲染的元素具有蓝色背景和红色文本,但它只是red. 这是示例:

const Test: React.FC<{ element: React.ReactElement }> = ({ element }) => {
  return React.cloneElement(element, {
    const isSelected = useIsSelected();
    style: { ...element.props.style, color: isSelected ? 'red' : 'black' }
  });
};

const TestWrapper: React.FC<{ element: React.ReactElement }> = ({
  element
}) => {
  // BackgroundColor is blue
  const { backgroundColor } = useTheme();
  return React.cloneElement(element, {
    style: { ...element.props.style, background: backgroundColor }
  });
};

export function App() {
  return <TestWrapper element={<Test element={<h1>Heading</h1>} />} />;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现这个目标?我可以以不同的方式执行此操作,但我必须能够从Test和访问钩子方法TestWrapper

简单的codesandbox示例:https ://codesandbox.io/s/serene-bassi-ve1ym?file=/src/App.tsx

Chr*_* B. 5

您正在TestWrapper克隆Test组件并向其应用style道具,这些道具不会被传递到它正在克隆本身的元素。仅返回克隆的元素不会创建引用相等性,因为对组件执行某些操作将影响其正在克隆的元素。您需要提供一个stylepropTest并将其传递给正在克隆的元素:

const Test: React.FC<{
  style?: React.CSSProperties;
  element: React.ReactElement;
}> = ({ element, style }) => {
  return React.cloneElement(element, {
    style: { ...element.props.style, ...style, color: "red" }
  });
};
Run Code Online (Sandbox Code Playgroud)

我在这里做了一个叉子。希望这有帮助!