Я пытаюсь отобразить сопоставленный массив, предоставленный реквизитами. Проблема в том, что массив не всегда доступен в зависимости от состояния родителя. Если я пытаюсь применить карту к несуществующему массиву, я получаю ошибку (естественно!). Итак, я попытался установить пустой массив по умолчанию, чтобы обойти ошибку.
Если я установил значение по умолчанию, REACT будет думать, что я пытаюсь отобразить объект. Следующий код был упрощен для примера, но конечный результат тот же:
export class Parent extends Component {
constructor(props) {
super(props);
this.state = {
// This array is not always available
// It's actually a deep property in an object
// done here for simplicity
myArray: [{name: 'foo'},{name: 'bar'}],
};
}
render() {
return (
<Child myArray = {this.state.myArray} />
);
}
}
import React, { Component } from 'react';
export class Child extends Component {
render() {
console.info(this.props.myArray); //=> [{...},{...}] Array
console.info(typeof this.props.myArray); //=> Object (wuh???)
this.props.myArray.map((item) => console.info(item.name)); //=> 'foo' then 'bar'
// Supply a default empty array here to avoid mapping an undefined
const list = this.props.myArray || [];
list.map((item) => {
return (
<li key = {item.name}>{item.name}</li>
);
});
return (
<ul> {list} </ul>
);
}
}
Uncaught Error: Objects are not valid as a React child (found: object with keys {name}). If you meant to render a collection of children, use an array instead.
Если я жестко закодирую массив и оставлю пустой массив по умолчанию, я не получу сообщения об ошибке:
const list = this.props.myArray.map((item) => {
return (
<li key = {item.name}>{item.name}</li>
);
});
Есть идеи, как применить карту к условному массиву?



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


Используйте свойства по умолчанию для вашего дочернего компонента как пустой массив:
import React, { Component } from 'react';
export class Child extends Component {
render() {
const list = this.props.myArray.map((item) =>(
<li key = {item.name}>{item.name}</li>
));
return (
<ul> {list} </ul>
);
}
}
Child.defaultProps = {
myArray: []
};
.map возвращает новый массив, а не модифицирует существующий (в любом случае этого делать не следует, поскольку свойства предназначены только для чтения).
Вы можете назначить .map новой переменной или выполнить сопоставление непосредственно в JSX:
<ul>{list.map(item => <li key = {item.name}>{item.name}</li>)}</ul>
Вы также можете просто выполнить {(this.props.myArray || []).map(...)} или использовать реквизиты по умолчанию или использовать [] (вместо null и т. д.) Для исходного состояния в родительском компоненте, соответствующем props.myArray.
В качестве примечания: в javascript нет типа "массив". Массив - это тоже просто объект.