React-Select : 如何在加载选项时显示 'Loading...'

React-Select : How to display 'Loading...' while loading options

我正在尝试将 'React-Select' 用于我的 WordPress 块组件 select post 类别。
我想要的是在加载类别时显示'Loading...',然后在加载完成时显示类别列表或'No Categories Found'。
使用我的代码,它在加载时显示 'No Categories Found',然后显示类别列表。

export default class Categories extends Component {
    constructor() {
        super( ...arguments );
        this.state = {cats: []};
    }
    componentDidMount () {
        return apiFetch({path: '/myoriginal-blocks/v1/categories'})
        .then(data => {
            this.setState({cats:data});
        })
    }
    onChangeCategories = newCategories => {
        this.props.setAttributes({ category: newCategories == null ? [] : newCategories });
    }
    render() {
        const { attributes } = this.props;
        const { category } = attributes;
        return (
            <>
                <div>
                    <label>Categories</label>
                    <Select
                        isMulti
                        isClearable
                        placeholder='Search categories...'
                        onChange={ this.onChangeCategories }
                        options={ this.state.cats }
                        value={ category && category }
                        noOptionsMessage={() => 'No Categories Found'}
                    />
                </div>
            </>
        );
    }
}

或者我可能必须使用 'Async-Select' 而不是 'React-Select' 但我不能很好地理解它的文档。
https://react-select.com/async
希望有人帮助我。谢谢。

您可以通过在您的状态中创建一个变量来保存加载状态来实现此目的。然后在获取数据之前设置此状态变量,并在获取数据后再次设置它。最后,您只需使用它在您的呈现方法中呈现不同的消息。

export default class Categories extends Component {
  constructor() {
    super(...arguments);
    this.state = {
      cats: [],
      isLoading: false // create a new state variable for loading
    };
  }
  componentDidMount() {
    this.setState((prevState) => ({
      ...prevState,
      isLoading: true
    }));

    return apiFetch({ path: "/myoriginal-blocks/v1/categories" }).then(
      (data) => {
        this.setState({ cats: data, isLoading: false });
      }
    );
  }

  onChangeCategories = (newCategories) => {
    this.props.setAttributes({
      category: newCategories == null ? [] : newCategories
    });
  };
  render() {
    const { isLoading } = this.state;
    const { attributes } = this.props;
    const { category } = attributes;
    return (
      <>
        {isLoading ? (
          <div>Loading...</div>
        ) : (
          <>
            <label>Categories</label>
            <Select
              isMulti
              isClearable
              placeholder="Search categories..."
              onChange={this.onChangeCategories}
              options={this.state.cats}
              value={category && category}
              noOptionsMessage={() => "No Categories Found"}
            />
          </>
        )}
      </>
    );
  }
}

你可以 isLoading react-select 组件的道具。

在您所在的州添加一个 属性 来管理加载

this.state = {cats: [], isLoading: true};

然后设置isLoading false

return apiFetch({ path: "/myoriginal-blocks/v1/categories" }).then(
      (data) => {
        this.setState({ cats: data, isLoading: false });
      }
    );

并在 Select 组件中传递 isLoading 属性

<Select
    isMulti
    isClearable
    placeholder='Search categories...'
    onChange={ this.onChangeCategories }
    options={ this.state.cats }
    value={ category && category }
    noOptionsMessage={() => 'No Categories Found'}
    isLoading={this.state.isLoading}
/>

我找到这个页面是因为在加载新列表数据时列表仍然显示以旧值打开的列表...像这样将 isLoading 和 ALSO 选项设置为空数组使得列表在我选择一个选项后消失并且正确显示加载指示器。这增加了好处,因为它不需要更改状态变量,并且您可以在渲染时处理数据,而不是保存本地状态(如上所述),这在大多数情况下会导致必须使用 getDerivedStateFromProps 或 useEffect 这会导致不必要的 re-rendering.

  <Select
    arrowRenderer={() => <FaChevronDown />}
    className={!isEmpty(mutationError) ? 'validation-error' : undefined}
    id={cellId}
    isDisabled={disableLOVField}
    isLoading={lovLoading} // here <---<<<
    matchPos="any"
    maxMenuHeight={180}
    menuPlacement="auto"
    menuPortalTarget={document.body}
    name={cellId}
    onChange={handleOnChange}
    onMenuOpen={() => {
      refetchRowConfig({
        ...configVariables,
        skipGetRowConfig: false,
      });
    }}
    options={lovLoading ? [] : listOptions} // and here <---<<<
    placeholder="Please Select"
    resetValue=""
    styles={{
      group: provided => ({
        ...provided,
        borderBottom: '1px solid #ccc',
      }),
      menuPortal: base => {
        const { zIndex, ...rest } = base;

        return { ...rest, zIndex: 9999 };
      },
    }}
    value={selectedValue}
  />;