简体   繁体   中英

react-select can load async data

I'm trying to build a select component using react-select plugin.

In the process of implementing this project, I have some kind of tricky problem with that. Check out my source code here: https://codesandbox.io/s/j148r99695

  1. The problem that I have is I want to fetch all genresList data from the server and mapping them to select component. But somehow or I do wrong something, It's not working. Please see source code above to help me.

  2. I fetch data from Movies component. Its work well and I pass a props to FormFilter component: <FormFilter genresList={this.state.genres} /> . And in the FormFilter component, I check this.props.genresList , it's available. But when I'm trying to assign it to FormFilter state and console.log("state", this.state.genres); that. It's empty. Anyone can tell me why?

  3. Default react-select using value and label to display data to select component. But you know some cases we have to custom that. I try it out by using map to transform to other arrays. But It's the best way? How can I custom valueKey and labelKey .

I'm using react-select beta version2.

UPDATE: I was fixed my project. Please check out the link below. Somehow it's not working. I was commend inside source code.

https://codesandbox.io/s/moym59w39p

So to make it works I have changed the FormFilter.js implementation:

import React, { Component } from "react";
import * as Animated from "react-select/lib/animated";
import AsyncSelect from "react-select/lib/Async";

class FormFilter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: "",
      selectedOption: "",
      genres: []
    };
  }

  selectGenreHandleChange = newValue => {
    const inputValue = newValue.replace(/\W/g, "");
    this.setState({ inputValue });
    console.log(inputValue);
  };

  componentDidMount() {
    this.genresOption();
  }

  filterGenres = inputValue => {
    const genres = this.genresOption();
    //HERE - return the filter
    return genres.filter(genre =>
      genre.label.toLowerCase().includes(inputValue.toLowerCase())
    );
  };

  promiseOptions = inputValue => {
    return new Promise(resolve => { // HERE - you have to return the promise
      setTimeout(() => {
        resolve(this.filterGenres(inputValue));
      }, 1000);
    });
  };

  genresOption() {
    const options = [];
    const genres = this.props.genresList.genres; //HERE - array is genres in genresList
        if (genres && genres instanceof Array) {
          genres.map(genre => options.push({ value: genre.id, label: genre.name}));
        }
    return options;
  }

  render() {
    const { inputValue } = this.state;

    if (this.state.genres) console.log("state", this.state.genres);

    if (this.props.genresList)
      console.log("Movies props", this.props.genresList);

    return (
      <div className="filter_form">
        <span className="search_element full">
          <label htmlFor="genres">Genres</label>
          <AsyncSelect
            className="select genres"
            classNamePrefix="tmdb_select"
            isMulti
            isSearchable="true"
            isClearable="true"
            cacheOptions
            components={Animated}
            value={inputValue}
            defaultOptions
            onInputChange={this.selectGenreHandleChange}
            loadOptions={this.promiseOptions}
          />
        </span>
      </div>
    );
  }
}

export default FormFilter;

I have write a comment "HERE - something" to let you know what I changed. There are not big problems :)

I did some changed in your FIDDLE and it's works for me

Something like

import React, {Component} from "react";
import { render } from 'react-dom';
import Movies from './Movies';

import "./styles.css";

class App  extends Component {
render() {
  return (
    <div className="App">
      <Movies />
    </div>
  );
}
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM