Conditional API call and send data in react-select

2020-05-01 08:10发布

问题:

import React, { Component} from 'react';  
import Select from 'react-select';  
import 'react-select/dist/react-select.css';

const partsType = [
    {value: 'front_parts', label: 'Part Condition-Front'},
    {value: 'left_parts', label: 'Part Condition-Left'},
    {value: 'back_parts', label: 'Part Condition-Back'},
    {value: 'right_parts', label: 'Part Condition-Right'},
    {value: 'top_bottom_parts', label: 'Part Condition-Top/Bottom'},
    {value: 'glass', label: 'Glass Condition'},
    {value: 'electrical_parts', label: 'Electrical Parts'},
    {value: 'non_electrical_parts', label: 'Non-Electrical Parts'}
];

const getParts = () => {
    return fetch(
      "http://localhost:4000/left_parts",
      {
          method: 'get'
      }
    )
      .then(response => {
          if(response.status >= 400) {
              throw new Error("error");
          }
          return response.json()
      })
      .then(parts => {
          let partsName = [];
          for(let part of parts) {
              partsName.push({value: part.promptCode, label: part.text})
          }
          return {options: partsName};
      })
      .catch(err => {
          console.log('could not fetch parts');
          console.log(err);
          return {options: []}
      })
};

class Assess extends Component {

    constructor(props) {
        super(props);
        this.state = {
            partsType:'front_parts'        
    };

    this.handlePartsType = this.handlePartsType.bind(this);

    handlePartsType = (item) => {
        this.setState({
            partsType: item.value
        });
    };

    render() {
        return (
            <div>
                <Select
                    clearable={false}
                    searchable={false}
                    value={this.state.partsType}
                    options={partsType}
                    onChange={this.handlePartsType}
                />

                <Select.Async
                    clearable={false}
                    searchable={false}
                    name="PartNamePolygon"
                    value={this.state.PartNamePolygon}
                    onChange={this.PartNamePolygonSelect}
                    loadOptions={getParts}
                />
            </div>
        );
    }
}

I had provided the snippet. what i'm doing now is i had made two drop down and using first drop down data of second one will be changed. Now in that i am not getting how to call different API according to this.state.partsType because according to its state value, its value will be passed in "getParts". How to achieve that ? to pass the its value to it so that different API will be called

回答1:

try like this

import React, { Component} from 'react';  
        import Select from 'react-select';  
        import 'react-select/dist/react-select.css';

        const partsType = [
            {value: 'front_parts', label: 'Part Condition-Front'},
            {value: 'left_parts', label: 'Part Condition-Left'},
            {value: 'back_parts', label: 'Part Condition-Back'},
            {value: 'right_parts', label: 'Part Condition-Right'},
            {value: 'top_bottom_parts', label: 'Part Condition-Top/Bottom'},
            {value: 'glass', label: 'Glass Condition'},
            {value: 'electrical_parts', label: 'Electrical Parts'},
            {value: 'non_electrical_parts', label: 'Non-Electrical Parts'}
        ];

        const getParts = (type) => {
            return fetch(
              `http://localhost:4000/${type}`,
              {
                  method: 'get'
              }
            )
              .then(response => {
                  if(response.status >= 400){
                  throw new Error("error");
                  }
                  return response.json()
              })
              .then(parts => {
                  let partsName = [];


                  for(let part of parts) {
                  partsName.push({value: part.promptCode, label: part.text})
                  }


                  return {options: partsName};
              })
              .catch(err => {
                  console.log('could not fetch parts');
                  console.log(err);
                  return {options: []}
              })

        };

        class Assess extends Component {

            constructor(props){
            super(props);
            this.state = {
                partsType:'front_parts'

            };

        this.handlePartsType = this.handlePartsType.bind(this);

        handlePartsType = (item) => {
              this.setState({
                  partsType: item.value
              }, getParts(item.value));

              };

        render() {

            return (
            <div>
            <Select
            clearable={false}
            searchable={false}
            value={this.state.partsType}
            options={partsType}
            onChange={this.handlePartsType}
            />

        <Select.Async
                                  clearable={false}
                                  searchable={false}
                                  name="PartNamePolygon"
                                  value={this.state.PartNamePolygon}
                                  onChange={this.PartNamePolygonSelect}
                                  loadOptions={getParts}
                                />

        </div>
            );
          }
        }


回答2:

There are couple of issues:

this.handlePartsType = this.handlePartsType.bind(this); is redundant. Also constructor does not have closing bracket. Select.Async is not supposed to be used to load options based on external value, it loads options when input changes.

Below is rewritten example:

		const partsType = [
		    {value: 'front_parts', label: 'Part Condition-Front'},
		    {value: 'left_parts', label: 'Part Condition-Left'},
		    {value: 'back_parts', label: 'Part Condition-Back'},
		    {value: 'right_parts', label: 'Part Condition-Right'},
		    {value: 'top_bottom_parts', label: 'Part Condition-Top/Bottom'},
		    {value: 'glass', label: 'Glass Condition'},
		    {value: 'electrical_parts', label: 'Electrical Parts'},
		    {value: 'non_electrical_parts', label: 'Non-Electrical Parts'}
		];
    
    // test wrapper for fetch to be removed to talk to backend
    const fetch = () => Promise.resolve({json: () => Promise.resolve([{promptCode: 'test', text: 'Test option'}])})

		const getParts = (partsType) => {
		    return fetch(
			  `http://localhost:4000/${partsType}`,
			  {
			      method: 'get'
			  }
			)
			  .then(response => {
			      if(response.status >= 400){
				  throw new Error("error");
			      }
			      return response.json()
			  })
			  .then(parts => {
			      let partsName = [];


			      for(let part of parts) {
				  partsName.push({value: part.promptCode, label: part.text})
			      }


			      return {options: partsName};
			  })
			  .catch(err => {
			      console.log('could not fetch parts');
			      console.log(err);
			      return {options: []}
			  })

		};

		class Assess extends React.Component {
      state = {
			    partsType:'front_parts'
			};

      handlePartsType = (partsType) => {
        getParts(partsType).then(({options}) =>
          this.setState({partsType, partsOptions: options})
        )
      };
      
      componentDidMount() {
        this.handlePartsType(this.state.partsType);
      }

		render() {
		    return (
		    <div>
			<Select
			clearable={false}
			searchable={false}
			value={this.state.partsType}
			options={partsType}
			onChange={({value}) => this.handlePartsType(value)}
			/>
		<Select
				                  clearable={false}
				                  searchable={false}
				                  name="PartNamePolygon"
				                  value={this.state.partNamePolygon}
				                  onChange={this.partNamePolygonSelect}
                          options={this.state.partsOptions}
				                />

		</div>
		    );
		  }
		}


ReactDOM.render(
  <div>
   <Assess/>
  </div>,
  document.getElementById('root')
)
    
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<script src="https://unpkg.com/classnames/index.js"></script>
<script src="https://unpkg.com/react-input-autosize@1.0.0/dist/react-input-autosize.js"></script>
<script src="https://unpkg.com/react-select@1.0.0-rc.3/dist/react-select.js"></script>


<link rel="stylesheet" href="https://unpkg.com/react-select@1.0.0-rc.3/dist/react-select.css">
</head>
<body>
<div id='root'></div>
</body>
</html>