Условный вызов API и отправка данных в ответ-выбор

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>
        );
    }
}

Я предоставил фрагмент. то, что я делаю сейчас, это то, что я сделал два раскрывающихся списка, и использование первого раскрывающегося списка данных второго будет изменено. Теперь я не понимаю, как вызывать другой API в соответствии с this.state.partsType, потому что в соответствии с его значением состояния его значение будет передано в «getParts». Как этого добиться? чтобы передать ему его значение, чтобы вызывался другой API


person Piyush    schedule 25.07.2017    source источник


Ответы (2)


попробуй так

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>
            );
          }
        }
person Sport    schedule 25.07.2017
comment
как тогда он получит значение этого типа? - person Piyush; 25.07.2017
comment
handlePartsType = (item) =› { this.setState({partsType: item.value }, getParts(item.value)); @Пиюш }; это даст вам ценность. - person Sport; 25.07.2017
comment
Это не сработает, так как setState не принимает Promise в качестве результата обратного вызова. На самом деле обратный вызов setState вызывается после обновления состояния, а обратный вызов не объединяется с состоянием. - person Max Vorobjev; 25.07.2017

Есть пара вопросов:

this.handlePartsType = this.handlePartsType.bind(this); является избыточным. Также у конструктора нет закрывающей скобки. Select.Async не должен использоваться для загрузки параметров на основе внешнего значения, он загружает параметры при изменении ввода.

Ниже переписан пример:

		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/[email protected]/dist/react-input-autosize.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-select.js"></script>


<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/react-select.css">
</head>
<body>
<div id='root'></div>
</body>
</html>

person Max Vorobjev    schedule 25.07.2017
comment
это не я спросил - person Piyush; 25.07.2017
comment
Вы можете увидеть в коде ответы на handlePartsType = (partsType) => { getParts(partsType).then(({options}) => this.setState({partsType, partsOptions: options}) ) }; запросы на основе первого варианта выбора и заполнить параметры для второго выбора. Пожалуйста, не стесняйтесь запускать фрагмент. - person Max Vorobjev; 25.07.2017