reactjs - React-Select 从 1.x 升级到 3.0.4 - 未显示选定值

我对 React 有点陌生,我正在尝试将 React 从旧版本升级到 16.9。

一切正常,但我必须将以下组件升级到版本 3.0.4。

问题是,当我选择一个值时,它已被选中,但我在屏幕上看不到所选选项,我只看到默认占位符。

我找不到几个解释我必须使用完整对象设置值的答案,根据我的理解,我正在这样做。

谁能帮我找出问题所在?

// @flow

import React, { Component } from "react";
import ReactSelect from "react-select";
import { isNil } from "lodash";
import type { FormProps } from "redux-form";
import cx from "classnames";
import { getClassName, addModifierTo } from "ui-kit/utils/component";
import { injectIntl, FormattedMessage } from "react-intl";
/* import "react-select/dist/react-select.css"; */
import "./Select.scss";

type Option = {
  label: string,
  value: string
}

type Props = {
  name?: string,
  options?: Array<Option>,
  className?: string
} & FormProps;

type State = {
  selectedOption: Object
}

const getInitOption = (multi, valueType) => (multi && valueType === "Array" ? [] : "");

class Select extends Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
      selectedOption: this.getOptionFromPropValue(),
      openUp:         false
    };
  }

  componentDidMount() {
    const { defaultValue, input } = this.props;

    if (input && defaultValue) {
      input.onChange(defaultValue);
    }
  }

  getOptionFromPropValue(props: Props = this.props) {
    const {
      defaultValue,
      input,
      multi,
      valueType = "String",
      value: valueFromProp
    } = props;
    let value = "";

    if (!isNil(defaultValue)) {
      value = defaultValue;
    }
    if (input && !isNil(input.value)) {
      ({ value } = input);
    }
    else if (valueFromProp) {
      value = valueFromProp;
    }

    let options;
    if (multi) {
      if (valueType === "String" || typeof value === "string") {
        value = value.split(",");
      }
      options = value.map(valueItem => ({ value: valueItem }));
    } else {
      options = [{ value }];
    }
    if (props.options) {
      options = options.map((option) => {
        const sameOption = props.options.find(item => item.value === option.value);
        if (sameOption) {
          return sameOption;
        }
        return option.value !== "" ? option : null;
      });
    }
    return multi ? options : options[0];
  }

  initialized: false

  UNSAFE_componentWillReceiveProps(nextProps) {
    const {
      loadedLabel, input, multi, valueType
    } = nextProps;

    if (!this.initialized) {
      this.setState({ selectedOption: this.getOptionFromPropValue(nextProps) });
      this.initialized = true;
    }

    if (this.selectedOption && !this.selectedOption.label && loadedLabel) {
      this.setState(prevState => ({ selectedOption: { ...prevState.selectedOption, label: loadedLabel } }));
    }

    if (input && !input.value) {
      this.setState({ selectedOption: getInitOption(multi, valueType) });
    }
  }

  render() {
    const {
      className,
      name,
      label,
      simple,
      creatable = false,
      asyncLoad = false,
      input,
      hasBorder = true,
      errorOffset = false,
      meta = {},
      onChange: onChangeEvent,
      onChangeReplace,
      initialized,
      defaultValue,
      multi,
      valueType = "String",
      maxHeight,
      ...props
    } = this.props;

    const msg = meta.error || meta.warning;

    let Tag;
    if (asyncLoad) {
      Tag =  creatable ? ReactSelect.AsyncCreatable : ReactSelect.Async;
    } else {
      Tag =  creatable ? ReactSelect.Creatable : ReactSelect;
    }

    const onChange = onChangeReplace || ((selectedOption) => {
      if (!selectedOption) {
        selectedOption = { value: "" };
      }
      let value;
      if (multi && Array.isArray(selectedOption)) {
        value = selectedOption.map(({ value: valueItem }) => valueItem);
        if (valueType === "String") {
          value = value.join(",");
        }
      } else {
        ({ value } = selectedOption);
      }
      if (input) {
        input.onChange(value);
      }
      if (onChangeEvent) onChangeEvent({ target: { name, value } });
      this.setState({ selectedOption });
    });

    // for fix bug with losing value on Blur (https://github.com/erikras/redux-form/issues/1185)
    const onBlur = () => input && this.state.selectedOption && input.onBlur(this.state.selectedOption.value);

    const onOpenHandler = () => {
      if (!isNil(this.elDOM)) {
        let inputEl = this.elDOM.input;
        if (!isNil(inputEl) && !(inputEl instanceof window.Element)) {
          inputEl = inputEl.input;
        }
        if (!isNil(inputEl) && !isNil(this.elDOM.menuContainer)) {
          const rect = inputEl.getBoundingClientRect();
          const menuRect = this.elDOM.menuContainer.getBoundingClientRect();
          const bottomDistance = window.innerHeight - rect.bottom;
          const openUp = bottomDistance < (menuRect.height + 20);
          this.setState({ openUp }, () => {
            if (openUp && rect.top < menuRect.height) {
              window.scrollTo(0, window.scrollY - (menuRect.height - rect.top));
            }
          });
        }
      }
    };

    const ccn = getClassName("Select");
    const modify = addModifierTo(ccn());
    const modifyWrap = addModifierTo(ccn("wrap"));

    console.log(this.state.selectedOption);

    // className "Select" is already present in Tag
    return (
      <div
        className={cx(
          ccn("wrap"),
          errorOffset && modifyWrap("error-offset"),
          className,
          meta.visited && meta.invalid && modify("invalid"),
          this.state.openUp && modify("up")
        )}
      >
        {label && <div className={ccn("label")}>{label}</div>}
        <Tag
          className={cx(
            simple && modify("simple"),
            !hasBorder && modify("no-border"),
          )}
          style={{ maxHeight }}
          name={name}
          multi={multi}
          {...input}
          clearable={false}
          backspaceRemoves={false}
          autosize={simple || false}
          value={this.state.selectedOption}
          onChange={onChange}
          onBlur={onBlur.bind(this)}
          onOpen={onOpenHandler}
          ref={(el) => { this.elDOM = el; }}
          placeholder=""
          noResultsText={<FormattedMessage id="select.noResultsText" defaultMessage="No results found" />}
          {...props}
        />
        {meta.visited && msg && <div className={ccn("validationMsg")}>{msg}</div>}
      </div>
    );
  }
}

export default injectIntl(Select);

最佳答案

我认为 React-Selectreact 版本是 16.8。

https://github.com/JedWatson/react-select/issues/3585

https://stackoverflow.com/questions/57945914/

相关文章:

c++ - 使用 ioctl 在 C++ 中以编程方式添加路由

python - 使用 image_slicer.py 将切片加入完整图像

reactjs - props 没有传递给 react native 中的另一个组件

sass - 找不到要导入的样式表

java - 从 jlink 图像创建所有包含 windows 可执行文件

reactjs - 尝试在 react-testing-library 中呈现组件时出错 - 得到一

npm - 无法在 Nexus Repository Manager 2.10 上发布库

azure-functions - Azure 函数无法在 Azure 门户中下载 PowerShe

node.js - 如何在 Node SOAP 中发送原始 XML 请求

javascript - 如何转到 Epubjs 中的特定页面