如何更改 react-select selected 选项的样式?

How to change style of react-select selected options?

现在 react-select 显示 selected 选项像这样

但是如果我们 select 20 个选项中有 10 个选项,那么这个块就会扩展。因此,与其显示每个 selected 选项,不如只显示第一个 selected 选项 + 剩余的 selected 选项计数会更好

如何在 react-select 中实现这一点?

我刚刚编写了这段代码,我认为它可以帮助你。这是直播 link https://djdz48.csb.app/ 和下面的片段:

const App = () => {
  const maxOptions = 2; // You can change the value

  const [values, setValues] = useState([]); // All values (in console)
  const [maxValues, setMaxValues] = useState({});
  const [isMaxVal, setIsMaxVal] = useState(false);

  const [actualOptions, setActualOptions] = useState(options);

  const handleChange = (e) => {
    let els = [];
    e.map((el) => els.push(el));

    if (els.length > maxOptions || values.length > maxOptions) {
      if (els.length === 0) {
        setValues(els);
        setIsMaxVal(false);
      } else {
        setIsMaxVal(true);

        const val = {
          key: 1,
          label: values[0]["label"] + " +" + (values.length + 1).toString()
        };

        setValues((values) => {
          return [...values, els[els.length - 1]];
        });

        setMaxValues(val);

        let opt = [];

        options.map((el) => {
          if (!values.includes(el) && !els.includes(el)) {
            opt.push(el);
          }
        });

        setActualOptions(opt);
      }
    } else {
      setValues(els);
    }
  };

  // values in real time

  useEffect(() => {
    console.log(values);
  }, [values]);

  return (
    <div className="App">
      <Select
        options={isMaxVal ? actualOptions : options}
        isMulti={true}
        onChange={(e) => handleChange(e)}
        value={values.length <= maxOptions ? values : maxValues}
      />
    </div>
  );
};

export default App;

据我所知,这不能直接通过 react-select props 完成,但您可以创建自定义包装器以获得所需的功能。

另一种方法是编写自定义组件并将其传递给 Select 组件,如下所示:

<Select
  isMulti
  isClearable
  options={options}
  closeMenuOnSelect={false}
  components={{
    MultiValue: CustomMultiValue
  }}
/>

react-selectallows you to write your custom component and use it。所以,这就是我所做的。首先,我寻找了我想要修改的组件并编写了一个自定义组件。应该有不同的可能性,但我决定编写一个自定义 MultiValue 组件。然后,我从 react-select 存储库中复制了代码并对其进行了修改。

Try a working sandbox here

新的自定义组件检查它是否是第三个选择的选项。如果它是第一个或第二个选项,它就像原始组件一样工作。如果是第三个选项,它打印数字,如果是另一个选项,它什么都不打印。

const CustomMultiValue = <
  Option,
  IsMulti extends boolean,
  Group extends GroupBase<Option>
>(
  props: MultiValueProps<Option, IsMulti, Group>
) => {
  const {
    children,
    className,
    components,
    cx,
    data,
    getStyles,
    getValue,
    index,
    innerProps,
    isDisabled,
    removeProps,
    selectProps
  } = props;

  const { Container, Label, Remove } = components;

  const additionalItems = getValue().length - MAX_ITEMS;

  return (
    <ClassNames>
      {({ css, cx: emotionCx }) => (
        <>
          {index < 2 ? (
            <Container
              data={data}
              innerProps={{
                className: emotionCx(
                  css(getStyles("multiValue", props)),
                  cx(
                    {
                      "multi-value": true,
                      "multi-value--is-disabled": isDisabled
                    },
                    className
                  )
                ),
                ...innerProps
              }}
              selectProps={selectProps}
            >
              <Label
                data={data}
                innerProps={{
                  className: emotionCx(
                    css(getStyles("multiValueLabel", props)),
                    cx(
                      {
                        "multi-value__label": true
                      },
                      className
                    )
                  )
                }}
                selectProps={selectProps}
              >
                {children}
              </Label>
              <Remove
                data={data}
                innerProps={{
                  className: emotionCx(
                    css(getStyles("multiValueRemove", props)),
                    cx(
                      {
                        "multi-value__remove": true
                      },
                      className
                    )
                  ),
                  "aria-label": `Remove ${children || "option"}`,
                  ...removeProps
                }}
                selectProps={selectProps}
              />
            </Container>
          ) : index === 2 ? (
            <Container
              data={data}
              innerProps={{
                className: emotionCx(
                  css(getStyles("multiValue", props)),
                  cx(
                    {
                      "multi-value": true,
                      "multi-value--is-disabled": isDisabled
                    },
                    className
                  )
                ),
                ...innerProps
              }}
              selectProps={selectProps}
            >
              <Label
                data={data}
                innerProps={{
                  className: emotionCx(
                    css(getStyles("multiValueLabel", props)),
                    cx(
                      {
                        "multi-value__label": true
                      },
                      className
                    )
                  )
                }}
                selectProps={selectProps}
              >
                {`+ ${additionalItems}`}
              </Label>
            </Container>
          ) : null}
        </>
      )}
    </ClassNames>
  );
};

在这里我找到了它的代码。非常有用的工作代码。

import React from "react";
import Select,{components} from 'react-select';
import '../App.css'

const options = [
    { value: '*', label: 'Select All' },
  { value: 'ocean', label: 'Ocean', color: '#00B8D9', isFixed: true },
  { value: 'blue', label: 'Blue', color: '#0052CC', isDisabled: true },
  { value: 'purple', label: 'Purple', color: '#5243AA' },
  { value: 'red', label: 'Red', color: '#FF5630', isFixed: true },
  { value: 'orange', label: 'Orange', color: '#FF8B00' },
  { value: 'yellow', label: 'Yellow', color: '#FFC400' },
  { value: 'green', label: 'Green', color: '#36B37E' },
  { value: 'forest', label: 'Forest', color: '#00875A' },
  { value: 'slate', label: 'Slate', color: '#253858' },
  { value: 'silver', label: 'Silver', color: '#666666' },
];

export default function ReactSelect() {
  const [value,setValue]=React.useState([])

  const  handleChange = (val) => {
    setValue( [...val] );
  }
  return (
    <div id="select">
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen </p>
      <Select
    onChange={handleChange}
    isMulti
    name="colors"
    options={options}
    className="basic-multi-select"
    classNamePrefix="select"
    allowSelectAll={true}
    closeMenuOnSelect={false}
        hideSelectedOptions={false}
    components={{ ValueContainer }}
  />
    </div>
  );
}

const ValueContainer = ({ children, ...props }) => {
  let [values, input] = children;
  if (Array.isArray(values)) {
    const val = (i= Number) => values[i].props.children;
    const { length } = values;
    switch (length) {
      case 1:
        values = `${val(0)} `;
        break;
      default:
        
        const otherCount = length - 1;
        values = `${val(0)}+ ${otherCount} `;
        break;
    }
  }
  return (
    <components.ValueContainer {...props}>
      {values}
      {input}
    </components.ValueContainer>
  );
};