首页 > 解决方案 > 如何将数据传递到 React 中的组件属性?

问题描述

许多 React 组件允许将自定义组件作为 props 传递,以便自定义 UI 的某些部分。一个流行的例子是react-select,它允许为其所有单独的子组件指定自定义替换。

在这个例子中,我使用了一个模态对话框组件,它允许在其componentsprop 中指定自定义页脚组件:

const Footer = () => <button>Close</button>;

const MyModal = ({ onClose, closeLabel }) => <Modal components={{ footer: Footer }}/>;

我想将某些数据传递给自定义组件。在这个特定的示例中,我想将onCloseandcloseLabel属性传递给Footer组件。我可以做的是声明Footer组件内联:

const MyModal = ({ onClose, closeLabel }) => (
    <Modal
        components={{ footer: () => <button onClick={onClose}>{closeLabel}</button> }}
    />
);

这种方法的问题是每次MyModal渲染时footer都会创建一个新组件,这会导致 React 完全重新创建页脚 DOM。在这个简单的示例中,这不会是一个大问题,但在更复杂的场景中,它会使事情变慢并且还会导致组件丢失其状态。将页脚组件包装进去useCallback()可以部分解决问题,但前提是传递到页脚组件中的值都没有改变。

我可以使用上下文来传递值,但这对于一个非常简单的问题来说似乎是一个非常复杂的解决方案。有没有其他选择?

标签: reactjs

解决方案


你可以做类似这样的事情:

export default function App() {
  return (
    <MyModal>
      <Footer /> // this will get the new props
    </MyModal>
  );
}

const Footer = ({ onClose, closeLabel }) => (
  <button onClick={onClose}>{closeLabel}</button>
);

const MyModal = ({
  onClose,
  closeLabel,
  children // here any child you pass to this component will have both onClose and closeLabel as props
}) => {
  return (
    <div>
      {React.Children.map(children, (child) => {
        return React.cloneElement(child, {
          onClose,
          closeLabel
        });
      })}
    </div>
  );
};

但无论如何,你的代码中有一些不清楚的地方,如果你在里面得到onCloseandcloseLabel作为道具,MyModal为什么不把它们传递给Footer你从哪里得到它们?如果你无法控制Modal组件,那么除了内联之外你什么也做不了


推荐阅读