[英]How to use props as component?
我有一个组件,我在其中接收包含 Link 组件(React 路由器,但可以是任何东西)的道具:
children: [
{
id: '1',
isActive: false,
label: 'Forms',
icon: <DestinationsIcon height={30} width={30} />,
link: <Link to={'somewhere'} />,
},
然后在接收这些道具的组件中,我可以从孩子那里提取道具:
<List>
{React.Children.map(children, (child) => {
if (!React.isValidElement(child)) {
return null;
}
return React.cloneElement(child, {
children: <div>{child.props.label}</div>,
});
})}
</List>
例如, child.props.label
确实返回了正确的 label。 但是我想做的是用link
道具替换包装<div>
,如下所示:
children: <child.props.link>{child.props.label}</child.props.link>,
这当然行不通。 如果我正在尝试使用 React.createElement:
children: React.createElement(child.props.link),
第一个参数应该是一个字符串,但我正在传递一个组件。 问题是我必须从外部接收带有自己上下文的 Link 组件,并且我无法重新创建它,否则我可以避免所有复杂性。
有谁知道将链接道具呈现为 JSX 包装器的正确方法是什么?
您的link: <Link to={'somewhere'} />
道具不是一个组件,它是一个元素。 这就是它作为一个组件的样子: link: Link
(然后你需要单独传递Link
的 props,也许是linkProps
):
children: [
{
id: '1',
isActive: false,
label: 'Forms',
icon: <DestinationsIcon height={30} width={30} />,
link: Link, // ***
linkProps: {to: 'somewhere'}, // ***
},
然后,要使用它,您需要通过带有大写第一个字符的标识符来引用它,因为这就是 React/JSX 区分标签(如div
或svg
)和组件的方式。
所以沿着这些思路:
const Link = child.props.link;
return React.cloneElement(child, {
children: <Link {...child.props.linkProps}>{child.props.label}</Link>,
});
...虽然这可能需要调整,因为我不清楚你为什么要进行提取和克隆。
这是一个更简单的示例,显示使用组件作为道具:
const { useState } = React; const Example = ({ link: Link, linkProps, label }) => { return <Link {...linkProps}>{label}</Link>; }; const SomeNiftyLink = ({ href, className, children }) => ( <a href={href} className={className}> {children} </a> ); const App = () => { return ( <Example link={SomeNiftyLink} linkProps={{ href: "#somewhere", }} label="The label" /> ); }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />);
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.