如何在 react-select 的选项中添加图标?

28

尝试在react-select中为选项添加图标。我从文件中导入了svg图标england.svggermany.svg。我创建了customSingleValue并将其放置在其中。

<Select components={{ SingleValue: customSingleValue }} />
标签已显示,但图标未显示。 演示在此处:https://stackblitz.com/edit/react-q19sor
import Select from 'react-select'
import { ReactComponent as IconFlagEngland } from "./england.svg";
import { ReactComponent as IconFlagGermany } from "./germany.svg";

const options = [
  { value: 'England', label: 'England', icon: <IconFlagEngland/> },
  { value: 'Germany', label: 'Germany', icon: <IconFlagGermany/> }
]

const customSingleValue = ({ options }) => (
    <div className="input-select">
        <div className="input-select__single-value">
            { options.icon && <span className="input-select__icon">{ options.icon }</span> }
            <span>{ options.label }</span>
        </div>
    </div>
);

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React'
    };
  }

  render() {
    return (
       <Select
            defaultValue={ options [0] }
            options={ options }
            /*styles={ selectCustomStyles }*/
            /*onChange={ changeSelectHandler }*/
            components={ {SingleValue: customSingleValue } }
        />
    );
  }
}

render(<App />, document.getElementById('root'));
4个回答

40

我已经找到了一个解决问题的方法。我的技巧类似于@canda

import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
import Select, { components } from "react-select";

const options = [
  { value: "England", label: "England", icon: "england.svg" },
  { value: "Germany", label: "Germany", icon: "germany.svg" }
];

const { Option } = components;
const IconOption = props => (
  <Option {...props}>
    <img
      src={require('./' + props.data.icon)}
      style={{ width: 36 }}
      alt={props.data.label}
    />
    {props.data.label}
  </Option>
);

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: "React"
    };
  }

  render() {
    return (
      <Select
        defaultValue={options[0]}
        options={options}
        components={{ Option: IconOption }}
      />
    );
  }
}

render(<App />, document.getElementById("root"));

1
精准修复,仅使用fontawesome图标,tvm。 - josevoid
对我来说可以工作,填充了下拉选项,但是选中的选项没有显示在输入框中。我已经指定了value={selectedValue},而且selectedValue也被正确填充了。有什么想法吗?谢谢。 - undefined

6

如果有人想在react-select中使用具有多选功能的图标,可以使用下面的代码:

const { MultiValue } = components;

const MultiValueOption = (props) => {
  return (
    <MultiValue {...props}>
      <img
        src={require("./" + props.data.icon)}
        style={{ width: 36 }}
        alt={props.data.label}
      />
      <span>{props.data.value}</span>
    </MultiValue>
  );
};

<Select
  options={options}
  components={{
    Option: IconOption,
    MultiValue: MultiValueOption,
  }}
  isMulti={true}
></Select>;

2
我认为问题在于您实际上没有导入SVG。如果您在任何地方直接尝试使用<IconFlagGermany/>,它会崩溃并显示以下消息:

元素类型无效:预期字符串(用于内置组件)或类/函数(用于复合组件),但却是:未定义。您可能忘记从定义该组件的文件中导出组件,或者可能混淆了默认和命名导入。

目前它没有崩溃,因为我认为您的customSingleValue函数不像您打算的那样工作(尚未查看,但几乎确定存在错误)。
如果您想以这种方式导入SVG,则需要在Webpack(或您选择的打包程序)中设置适当的加载器。也许像这样:https://www.npmjs.com/package/react-svg-loader 然而,另一种解决方案是将SVG正确导出为组件,就像这个演示从您的代码分支中派生的一样:https://stackblitz.com/edit/react-5gvytm

1
选项文本旁边没有图标。 - Penny Liu
当前版本的问题已经导入了标志图标,因此不确定这个答案在说它没有被导入时看到了什么。 - coppereyecat

0

这是我在@Penny Liu的帮助下完成的

import React from 'react';
import Select, { components } from 'react-select';
import { ReactComponent as MyIcon } from './my-icon.svg';

const options = [
  {
    value: 'hello',
    label: 'Hello',
    Icon: MyIcon,
  },
  // ...
];

const { Option } = components;

function IconOption(props: any) {
  const {
    data: { label, Icon },
  } = props;

  return (
    <Option {...props}>
      <div className="flex items-center gap-2">
        {Icon && <Icon />}
        <span>{label}</span>
      </div>
    </Option>
  );
}

export default function App() {
  return (
    <Select
      options={options}
      components={{ Option: IconOption }}
      // ...
    />
  );
}

这个方法也起作用了

<SelectComponent
  options={options}
  getOptionLabel={(props: any) => {
    const { Icon, label } = props;
    return (
      <div tw="flex items-center gap-2">
        {Icon && <Icon />}
        <span>{label}</span>
      </div>
    ) as unknown as string;
  }}
/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接