![](/img/trans.png)
[英]What is the correct way to correctly visualize a component React in top of another?
[英]What is the React way of inserting an icon into another component?
我正在尝试创建一个 WithIcon 包装器组件,它将一个子(图标)插入到包装的组件中。
假设我有一个按钮:
<Button>Add item</Button>
我想创建一个组件 WithIcon ,它将像这样使用:
<WithIcon i="plus"><Button>Add item</Button></WithIcon>
最终我想要实现的是:
<Button className="with-icon"><i className="me-2 bi bi-{icon}"></i>Add item</Button>
请注意添加的 className 和 Button 正文中的标记。
我试图弄清楚 WithIcon 组件的代码应该是什么样子。 实现此结果的 React 方法是什么?
最难的部分是使用WithIcon
的规则 我们只有一个吗? 我们只会在最左边吗? 类似的东西。
但是,如果我们以您为榜样。 我们可以相对地为WithIcon写这样的东西
const WithIcon = ({ i, children }) => {
return React.Children.map(children, (child) => {
return (
<>
<i className={`me-2 bi bi-${i}`}></i>
{React.cloneElement(child, { className: "with-icon" })}
</>
);
});
};
然后我们可以按照您想要的方式使用它
<WithIcon i="plus"><Button>Add item</Button></WithIcon>
我们所做的只是循环遍历子节点,这些子节点的反应是您放入其中的任何嵌套 jsx(在我们的例子中为按钮)
你可以在这里找到我的小提琴: https://codesandbox.io/s/react-font-awesome-forked-321tz?file=/src/index.js
更新所以我之前的回答并不完全符合我们想要的最终结果。 遗嘱必须是主要父母
这个想法还是和之前一样,但是这里我们在推断我们在 WithIcon 中传递的组件的类型 这也增加了当我们在WithIcon
中传递嵌套组件时的保护措施
const WithIcon = ({ i, children }) => {
return React.Children.map(children, (child) => {
const MyType = child.type; // So we can get the Button
return (
<MyType className="with-icon">
<i className={`me-2 bi bi-${i}`}></i>
{(React.cloneElement(child, {}), [child.props.children])}
</MyType>
);
});
};
我想我会 go 睡觉我会在以后更新解释的 rest。 在这里查看小提琴: https://codesandbox.io/s/react-font-awesome-forked-y43fx?file=/src/components/WithIcon.js
请注意,此代码不会保留传递组件的其他道具,但您可以通过在MyComponent
中添加 {...child.props} 来相对添加它,这只是(反射之类?)推断组件。
当然也有像 HOC Enhancers 这样的另一种选择来执行此操作,但这会增加您如何声明组件 api 的复杂性。 所以选择最适合你的朋友
也许尝试使用更高阶的组件?
const withIcon = (icon, Component) => ({children, ...props}) => {
return (
<Component className="with-icon" {...props}>
<i className=`me-2 bi bi-${icon}` />
{children}
</Component>
);
}
那么用法是
const ButtonWithIcon = withIcon("your-icon", Button);
<ButtonWithIcon>Add Item</ButtonWithIcon>
根据我对反应的经验,它通常归结为使用组件内部的属性,例如此处( https://material-ui.com/api/button/ )或像我描述的那样的更高阶组件。
React 中使用了两种常见的模式来实现这种组合:
首先为您的按钮定义一个组件:
const Button = ({ className, children }) => (
<button className={className}>{children}</button>
);
那么高阶组件可以这样实现:
const withIcon = (Component) => ({ i, className = '', children, ...props }) => (
<Component {...props} className={`${className} with-icon`}>
<i className={`me-2 bi bi-${i}`} />
{children}
</Component>
);
用法:
const ButtonWithIcon = withIcon(Button);
<ButtonWithIcon i="plus">Add Item</ButtonWithIcon>
首先定义图标的上下文提供程序:
import { createContext } from 'react';
const Icon = createContext('');
const IconProvider = ({ i, children }) => (
<Icon.Provider value={i}>{children}</Icon.Provider>
);
然后是你的组件:
import { useContext } from 'react';
const Button = ({ className = '', children }) => {
const i = useContext(Icon);
if (i) {
className += ' with-icon';
children = (
<>
<i className={`me-2 bi bi-${i}`} />
{children}
</>
);
}
return (
<button className={className}>{children}</button>
);
};
用法:
<IconProvider i="plus"><Button>Add Item</Button></IconProvider>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.