Динамический выбор реакции с помощью Axios - PullRequest
0 голосов
/ 07 января 2019

Я только начинаю с добавления некоторого React в мой интерфейс Ruby on Rails.

У меня есть две модели данных, называемые coffee_beans и countries.

Я хочу добавить выпадающий список в форму для coffee_beans, который тянет в стране, как поля id, так и country_name. Мне нужно отправить идентификатор в таблицу coffee_beans.

Я могу нормально получать данные через axios, но я изо всех сил стараюсь, чтобы данные отображались в моем раскрывающемся списке.

Я использую React-Select.

import React from 'react';
import axios from 'axios';
import Select from 'react-select';

class Country extends React.Component {
    constructor() {
        super();
  }

  componentDidMount() {
    axios.get(`/countries.json`)
      .then(res => {
        const countries = res.data;
        this.setState({ countries });
      })
  }

  render() {
    let optionItems = countries.map(countries => 
        <option key={countries.id}>{countries.country_name}</option>
    );

    return (
        <div className="">
        <label htmlFor="coffee_beans_countries">Country</label>
            <Select id="country" name="coffee_beans[countries]" options={optionItems} />
        </div>
    )
  }
}

export default Country

представленный элемент

import React from 'react'
import ReactDOM from 'react-dom'
import Country from 'Country'

document.addEventListener('turbolinks:load', function() {
    var element = document.getElementById("country-component");
    ReactDOM.render(<Country />, element);
});

Update Теперь у меня есть код ниже, но я получаю сообщение об ошибке:

warning.js: 33 Предупреждение: можно обновить только смонтированный или монтированный составная часть. Обычно это означает, что вы вызвали setState, replaceState или forceUpdate для неустановленного компонента. Это неоперация.

import React from 'react';
import axios from 'axios';
import Select from 'react-select';

class Country extends React.Component {
    state = {
        countries: []
      }

  componentDidMount() {
    axios.get(`/countries.json`)
      .then(res => {
        const countries = [];
        this.setState({ countries });
      });
      console.log(countries)
  }

  render() {
    let optionItems = this.state.countries.map(countries => 
        <option key={countries.id}>{countries.country_name}</option>
    );

    return (
        <div className="">
        <label htmlFor="coffee_beans_countries">Country</label>
            <Select id="country" name="coffee_beans[countries]" options={optionItems} />
        </div>
    )
  }
}

export default Country

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Поскольку страны - это единственное в государстве, попробуйте this.state.map(countries => ... -ИЛИ ЖЕ- В componentDidMount, this.setState({countries: countries})

0 голосов
/ 29 января 2019

Для обновленного предупреждения: у меня была та же проблема пару дней назад, но я использовал api fetch, поэтому не знаю, сработает ли она. Я просто сделал свой componentDidMount () async и поместил await перед каждым асинхронным методом, который я вызвал внутри него. Это конечный результат:

async componentDidMount() {
    await this._getUserData();
}

_getUserData = async () => {
    try {

        const response = await fetch(url);
        this.setState({firstAccess: responseJson.data.name});

    } catch(error) {
        console.log(error);
    }
}

Я новичок в React и JavaScript, поэтому я не уверен, почему он работает, но похоже, что React просто пытается предупредить вас, что setState () внутри Promise может быть вызван, когда компонент еще не смонтирован. , эта ситуация произойдет, если вы вызовите другой setState ниже вашего вызова axios, что вызовет повторную визуализацию компонента (не знаю, считается ли это отключенным, как сказано в предупреждении), и произойдет изменение, обещание setState будет вызвано прямо здесь. Если вы сделаете componentDidMount асинхронным, это позволит вам подождать, пока обещание будет решено, и у вас не возникнет проблема. Но опять же ... я не уверен, ха-ха.

0 голосов
/ 07 января 2019

let optionItems = countries.map

должно быть

let optionItems = this.state.countries

и вам также нужно установить начальное состояние. Итак:

import React from 'react';
import { render } from 'react-dom';
import Select from 'react-select';

class Country extends React.Component {
  state = {
    countries: []
  }

  componentDidMount() {
    const countries = []
    this.setState({ countries });
  }

  render() {
    let optionItems = this.state.countries.map(countries =>
      <option key={countries.id}>{countries.country_name}</option>
    );

    return (
      <div className="">
        <label htmlFor="coffee_beans_countries">Country</label>
        <Select id="country" name="coffee_beans[countries]" options={optionItems} />
      </div>
    )
  }
}

render(<Country />, document.getElementById('root'));

Живой пример здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...