[英]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.