Пытаетесь получить значение идентификатора из выпадающего списка имен, используя Form.Select с Semantic-UI-React?

Я использую Semantic-UI-React в своем проекте React/Rails и пытаюсь использовать раскрывающееся меню Form.Select в более крупной форме внутри модального окна. Мне нужно получить значение .id (animal.id) из выбора, показывающего пользователя .name (animal.gnames) — gnmaes — это просто атрибут, который я использую в своих целях, чтобы избежать путаницы.

Я использую options= опору Form.Select, я сопоставляю массив элементов, а затем назначаю item.gname title, чтобы получить хороший выпадающий список имен для пользователя. Затем мне нужно получить идентификатор, который находится в этом большом массиве, и отправить его в запрос на выборку. Я пробовал каждую комбинацию реквизитов, но не могу получить идентификатор из массива и в то же время отображать имена.

Вот код. Я вырезал последнюю половину, так как она не имеет отношения к проблеме:


import React, { Component } from "react";
import { withRouter } from "react-router-dom"
import ActiveStorageProvider from 'react-activestorage-provider'
import { Menu, Button, Modal, Header, Icon, Image, Form, Input, Select, Label } from "semantic-ui-react"
import { Link } from "react-router-dom"
const value = null
const options = null

class Navigation extends Component {

  state = { modalOpen: false,
            title: "",
            body: "",
            animal: "",
            geotag: false,
            animals: []
          };

  componentDidMount() {
   fetch('http://localhost:9000/api/v1/animals')
   .then(r => r.json())
   .then(animals => {
     this.setState({ animals: animals })
   })
 };

  handlechange = (event) => {
    this.setState({ [event.target.name]: event.target.value })
  };

  submitForm = (event) => {
    this.props.postSighting(this.state.title, this.state.body) 
    // NEED TO GET ANIMAL.ID IN HERE!!!
  };

  // THIS METHOD IS READY TO GO FOR DOING THE ITERATION AND SET STATE BUT COULD NOT GET IT OT WORK. 
  // HAD ISSUE WITH A FETCH AND SET STATE LOOP CALLS

  selectAnimal = () => {
    const mappedAnimals = this.state.animals.map(animal => {
      this.setState({ animal: animal.gname })
    })
    return mappedAnimals
  };


  render () {
    return (

//.......SKIP TO THE CODE THAT MATTERS

          <Form.Select
               label = "Animal"
               name = "Animal"
               onChange = {this.handlechange}
               selection= // WHAT GOES HERE?
               width = {8}
               value= // WHAT GOES HERE?
               compact
               options = {this.state.animals.map(animal => ({
                 return
                    name: animal.id,
                    key: animal.id,
                    value: animal.id,
                    text: animal.gname
               }))}
           /> // HOW DO I GET ANIMAL.ID TO MY SUBMIT FORM FUNCTION? 


Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
1 642
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Здесь много чего происходит, поэтому позвольте мне попытаться разобрать это по частям в комментариях к коду. Дайте мне знать, если что-то не ясно.

class Navigation extends Component {
  state = {
    modalOpen: false,
    title: "",
    body: "",
    animal: "",
    geotag: false,
    animals: []
  };

  componentDidMount() {
    fetch("http://localhost:9000/api/v1/animals")
      .then(r => r.json())
      .then(animals => {
        this.setState({ animals: animals });
      });
  }

  /**
   * When a user selects an option in the dropdown, the following will happen:
   *  1. this.handlechange gets called
   *  2. Component's state gets updated to look like:
   *      {
   *        ...state,
   *        "Animal": <id of animal selected>
   *      }
   * Side note: you will have to access this "Animal" value through this.state.Animal
   * where the uppercase 'A' is very important. This is really prone to typos and not
   * recommended. To fix this I would change your <Form.Select> to have a lowercase
   * name attribute.
   */
  handlechange = (event, { name, value }) => {
    // We need to use { name, value } instead of event.target.name, etc
    // due to how Semantic UI handles events. More info here:
    // https://github.com/Semantic-Org/Semantic-UI-React/issues/638
    this.setState({ [name]: value });
  };

  submitForm = event => {
    this.props.postSighting(this.state.title, this.state.body);

    // Recall from above that this.state.Animal contains the animal id currently selected
    // so we can access it directly with this.state.Animal
    const animalId = this.state.Animal;

    // do stuff with animalId...
  };

  /**
   * If this is called, it will destroy the array of animals you have in your state and replace it with a gname
   * from one of the animals. You probably don't want this to happen.
   * Not sure what you are trying to do here, what do you use the return value for?
   * Also, this will return an array filled with 'undefined' since you don't return anything in the animals.map callback.
   */
  selectAnimal = () => {
    const mappedAnimals = this.state.animals.map(animal => {
      this.setState({ animal: animal.gname });
    });
    return mappedAnimals;
  };

  render() {
    return (
      //.......SKIP TO THE CODE THAT MATTERS

      <Form.Select
        label = "Animal"
        name = "Animal" // this is the name that gets passed to 'handlechange' as event.target.name
        onChange = {this.handlechange}
        // selection: this isn't a valid prop for Form.Select and will be ignored regardless of value
        width = {8}
        // value: we don't need to worry about this since Form.Select will handle it
        compact
        options = {this.state.animals.map(animal => ({
          // return: was this a typo?
          name: animal.id,
          key: animal.id,
          value: animal.id, // This is the value that gets passed to 'handlechange' as event.target.value
          text: animal.gname
        }))}
      />
    );
  }
}

Хорошо, отлично, и я думаю, что это многое проясняет. Вопрос: откуда вы взяли this.state.Animal? У меня есть this.state.animal. Мне нужно изменить на верхний регистр? Я никогда раньше не слышал об этой функциональности с прописными буквами. Кроме того, как состояние обновляется с помощью раскрывающегося списка, если я явно не объявляю его в семантическом компоненте Form.Select?

Demian Sims 25.03.2019 14:29

оооо теперь вижу. Хорошо, да, извините, я новичок в React. Вы имеете в виду заглавное «Животное» в компоненте <Form.Select под «именем». Мне нужно изменить имя в инициализаторе состояния. Я понял теперь. Собираюсь попробовать.

Demian Sims 25.03.2019 15:10

Я все еще получаю «неопределенный» при вызове event.target.value в отладчике в handleChangeEvent

Demian Sims 25.03.2019 15:26

Все еще не в состоянии зафиксировать значение. Ааааааааааааааааааааааааааааа

Demian Sims 25.03.2019 15:42

Хорошо, я наконец понял. У меня не был правильный метод handleChangeEvent. Должно быть: handleChangeEvent = (e, { name, value }) => this.setState({ [name]: value })

Demian Sims 25.03.2019 17:00

Ах, я пропустил это, извините, обычно event.target.value будет работать, но только для собственных событий браузера. В этом случае собственное событие не запускается из-за реализации раскрывающегося списка в семантическом пользовательском интерфейсе. Подробнее см. github.com/Semantic-Org/Semantic-UI-React/issues/638

miyu 25.03.2019 18:03

@miyu допустим, в объекте животного есть еще один ключ description. как description: animal.description, как бы вы могли обновить состояние с помощью клавиши description в той же функции handleChangeEvent?

DJ2 20.08.2019 20:58

@ DJ2 Немного сложно передать description напрямую handlechange, но вы можете использовать value в handlechange (животное id) для поиска в вашем списке животных, найти животное с соответствующим id и установить свое состояние, которое способ

miyu 22.08.2019 06:33

После долгих исследований и некоторой помощи от @miyu оказалось, что это работает:

  <Form.Select
            fluid
            onChange = {this.handleChangeEvent}
              placeholder='select animal'
              label = "Animal"
              name = "animal"

               width = {8}
               selection
               options = {this.state.animals.map(animal => ({
                 name: animal.gname,
                 key: animal.id,
                 value: animal.id,
                 text: animal.gname
               }))}
            />

и ваш handleChangeEvent должен выглядеть так:

handleChangeEvent = (e, { name, value }) => this.setState({ [name]: value })

Другие вопросы по теме