Формы HTML/JSX в React отображаются как [object Object] вместо фактического значения в массиве

Я изучаю React и не знаю Javascript. Цель состоит в том, чтобы создать раскрывающееся меню, используя значения, полученные из API. Вместо того, чтобы отображать фактические значения, каждый параметр в моей форме отображает [object Object], а не значения из API.

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

class Test extends React.Component {

constructor() {
    super();
    this.state = {
        randomName: [],
    };
}

Вот что я получаю из API:

componentDidMount() {       
    fetch('https://randomuser.me/api/?results=10')
    .then(results => {
        return results.json();
    }).then(data => {
        let randomName = data.results.map((info => {
            return(             
                <div key = {info.results}>
                    {info.name.first} {info.name.last} - {info.email}
                </div>
            )
        }))             
        this.setState({randomName: randomName});
        console.info("state", this.state.randomName);
    })
}

И вот где я пытаюсь создать раскрывающийся список (в том же компоненте):

render() {      
    var test = this.state.randomName[0];        
    return (
    <div>               
        {test} { /* value prints as expected here */}           
        <form>
            <select>
                <option>{test}</option> { /* value prints as [object Object] here */}    
                <option>first last - [email protected]</option>
                <option>first last - [email protected]</option>
                <option>first last - [email protected]</option>
            </select>       
        </form>
    </div>
    )       
}

Я ожидаю, что первый вариант в раскрывающемся списке будет отображаться как «someFirstName someLastName — someEmail», но вместо этого он отображается как «[object Object]». Кажется, это специфично для форм.

Использование JSON.stringify(test) возвращает то, что выглядит как строка всего объекта JSON. Почему использование {test} где-то в html правильно работает с этим объектом, но не при включении в параметр формы?

Вы помещаете <div> в свой массив; вставить div в JSX, как это, не проблема, но <option> не поддерживает дочерние элементы, что означает, что переменная принудительно преобразуется в строку. По умолчанию [object Object].

Chris G 07.02.2019 19:04

Один из способов исправить это — сопоставить массив с объектом, содержащим как div, так и текст: codeandbox.io/s/2okr9xjj4r

Chris G 07.02.2019 19:10

@ChrisG Заполняет ли это только один элемент массива? Когда я меняю размер массива randomName: 10, а затем var test = this.state.random[1], это ломается.

Rial Johnson 07.02.2019 19:36
randomName: 10 не меняет размер, он устанавливает this.state.randomName на 10. число не имеет [1]. Я действительно не знаю, какова ваша цель здесь; вы пытаетесь превратить ответ JSON в варианты? Опять же: ваш исходный код превратил группу объектов в группу объектов-элементов React <div>. Вставка их в JSX — это нормально, вставка их в <option> — нет.
Chris G 07.02.2019 19:56

@ChrisG Упс, я потерял скобки при форматировании. Должен быть randomName: [10]. Цель состоит в том, чтобы установить для каждого значения из API разные параметры в раскрывающемся списке. Я также хотел бы, чтобы количество параметров менялось динамически, поэтому я, вероятно, все равно не хочу устанавливать размер массива.

Rial Johnson 07.02.2019 20:02

Я обновил пример codeandbox.

Chris G 07.02.2019 20:05

@ChrisG Да, это именно то, что я искал! Не могли бы вы поделиться своим мнением о том, почему явный доступ к другим элементам массива не работал, как я ожидал в предыдущем примере? Мне также любопытно, почему использование конструктора, подобного моему оригиналу, не будет работать с этим кодом. Даже использование this.state при инициализации, кажется, ломает ситуацию. Цените помощь!

Rial Johnson 07.02.2019 20:15

Давайте продолжить обсуждение в чате.

Rial Johnson 07.02.2019 20:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
1 874
2

Ответы 2

<div id = "example"></div>
<script type = "text/babel">
  let Dropdown = mui.react.Dropdown,
  DropdownItem = mui.react.DropdownItem;

class Example extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      randomName:''
    }
  }

  componentDidMount() {
    fetch('https://randomuser.me/api/?results=10')
      .then(results => {
        return results.json();
      }).then(data => {
      let randomName = data.results.map((info => {
        return(
          <DropdownItem key = {info.results}>
            {info.name.first} {info.name.last} - {info.email}
          </DropdownItem>
        )
      }))
      this.setState({randomName: randomName});
      console.info("state", this.state.randomName);
    })
  }
  render() {
    return (
      <div>
        <Dropdown color = "primary" label = "Dropdown">
          {this.state.randomName}
        </Dropdown>

      </div>
    );
  }
}

ReactDOM.render(<Example />, document.getElementById('example'));
</script>

Вместо добавления div в состояние componentDidMount вы можете сделать следующее:

componentDidMount() {       
    fetch('https://randomuser.me/api/?results=10')
    .then(results => {
        return results.json();
    }).then(data => {
        let randomName = data.results             
        this.setState({ randomName });
    })
}

и после этого в методе рендеринга:

renderInfo = () => {
   const {randomName} = this.state 
   return (
        {randomName.map((info) => <option>{info.name.first} {info.name.last} - {info.email}</option>)}
   )
}

render() {             
    return (
    <div>                       
        <form>
            <select>
                {this.renderInfo()}
            </select>       
        </form>
    </div>
    )       
}

Надеюсь, это может помочь, спасибо

Как будет выглядеть ваш конструктор для этого? Не компилируется с моим кодом.

Rial Johnson 07.02.2019 19:57

Все еще не мог заставить это скомпилировать. В любом случае, теперь я знаю проблему и нашел другое решение. Цените помощь!

Rial Johnson 07.02.2019 20:26

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