簡體   English   中英

將圖標插入另一個組件的 React 方式是什么?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM