Я изучаю 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, так и текст: codeandbox.io/s/2okr9xjj4r
@ChrisG Заполняет ли это только один элемент массива? Когда я меняю размер массива randomName: 10, а затем var test = this.state.random[1], это ломается.
randomName: 10 не меняет размер, он устанавливает this.state.randomName на 10. число не имеет [1]. Я действительно не знаю, какова ваша цель здесь; вы пытаетесь превратить ответ JSON в варианты? Опять же: ваш исходный код превратил группу объектов в группу объектов-элементов React <div>. Вставка их в JSX — это нормально, вставка их в <option> — нет.
@ChrisG Упс, я потерял скобки при форматировании. Должен быть randomName: [10]. Цель состоит в том, чтобы установить для каждого значения из API разные параметры в раскрывающемся списке. Я также хотел бы, чтобы количество параметров менялось динамически, поэтому я, вероятно, все равно не хочу устанавливать размер массива.
Я обновил пример codeandbox.
@ChrisG Да, это именно то, что я искал! Не могли бы вы поделиться своим мнением о том, почему явный доступ к другим элементам массива не работал, как я ожидал в предыдущем примере? Мне также любопытно, почему использование конструктора, подобного моему оригиналу, не будет работать с этим кодом. Даже использование this.state при инициализации, кажется, ломает ситуацию. Цените помощь!
Давайте продолжить обсуждение в чате.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


<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>
)
}
Надеюсь, это может помочь, спасибо
Как будет выглядеть ваш конструктор для этого? Не компилируется с моим кодом.
Все еще не мог заставить это скомпилировать. В любом случае, теперь я знаю проблему и нашел другое решение. Цените помощь!
Вы помещаете
<div>в свой массив; вставить div в JSX, как это, не проблема, но<option>не поддерживает дочерние элементы, что означает, что переменная принудительно преобразуется в строку. По умолчанию[object Object].