Код дает мне эту ошибку «TypeError: Cannot read property 'name' of undefined», хотя, когда я console.info, он дает мне объект
import React from "react";
class Random extends React.Component {
constructor(props) {
super(props);
this.state = {
breweries: []
};
}
componentDidMount() {
fetch("https://api.openbrewerydb.org/breweries")
.then(response => response.json())
.then((data) => {
this.setState({
breweries: data,
})
})
}
render() {
const brewery = this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
return(
<div>{brewery.name}</div>
)
}
}
export default Random;
когда я консоль регистрирую только пивоварню
вы получаете это в своей консоли: [ ], затем [...your data]? так что делать две вещи в консоли?
нет, я просто получил предмет



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


Пока асинхронный запрос не завершится,
this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)]
фактически вернет undefined, так как
Math.floor(Math.random()*this.state.breweries.length)
вернет 0, а поскольку this.state.breweries - пустой массив, вернет undefined
([][0] -> undefined).
Вы должны обеспечить возможность того, что brewery еще не определен, например:
<div>{brewery && brewery.name}</div>
Вы должны убедиться, что вы получили данные, прежде чем пытаться получить доступ к индексу массива. Ваша случайная математика будет оценивать 0, когда массив пуст, что приведет к undefined
import React from "react";
class Random extends React.Component {
constructor(props) {
super(props);
this.state = {
breweries: null
};
}
componentDidMount() {
fetch("https://api.openbrewerydb.org/breweries")
.then(response => response.json())
.then((data) => {
this.setState({
breweries: data,
})
})
}
render() {
if (this.state.breweries) {
const brewery = this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
return(
<div>{brewery.name}</div>
)
}
return null
}
}
export default Random;
Я не понимаю, что вы изменили в его коде, или это для справки?
Есть два подхода к этому вопросу.
Подход 1: UNSAFE_componentWillMount()
Вы можете использовать UNSAFE_componentWillMount() вместо componentDidMount(). UNSAFE_componentWillMount() выполняется до рендеринга компонента, поэтому данные будут в состоянии до рендеринга содержимого. Это должно избавить от ошибки.
Подход 2: проверка состояния - !Empty
В свой метод render вы можете добавить оператор if, который говорит, что breweries - это null, если нет данных в состоянии, иначе пивоваренные заводы равны this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)].
Что-то вроде этого:
render() {
const { breweries } = this.state;
let brewery;
if (breweries.length === 0){
brewery = null;
} else {
brewery=
this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
}
return(
<div>{brewery.name}</div>
)
}
Для дополнительной страховки вы можете совместить два подхода. Если бы вы это сделали, ваш компонент выглядел бы так:
import React from "react";
class Random extends React.Component {
constructor(props) {
super(props);
this.state = {
breweries: []
};
}
componentWillMount() {
fetch("https://api.openbrewerydb.org/breweries")
.then(response =>{ return response.json() })
.then((data) => {
this.setState({
breweries: data,
})
})
}
render() {
const { breweries } = this.state;
let brewery;
if (breweries.length === 0){
brewery = null;
} else {
brewery=
this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
}
return(
<div>{brewery.name}</div>
)
}
}
export default Random;
Это должно сработать. Надеюсь это поможет.
Обновлено: ВНИМАНИЕ
Я написал willMount (), но это должно быть UNSAFE_componentWillMount (). componentWillMount() не будет работать после версии 17. UNSAFE_componentWillMount() будет работать после версии 17. Приносим извинения. Забыл написать небезопасно.
Это вредный ответ. Я бы никому не предлагал использовать componentWillMount.
что-то не так с componentWillMount. Небезопасно будет работать через версию 17. Лично я бы пошел не по этому пути. Я бы передал эти данные как опору или использовал сокращение. Но для обстоятельств владельца unsafe...willmount подойдет. Я также включил другой подход на случай, если владельцу будет неудобно использовать небезопасный метод жизненного цикла.
при консольном логе какой
brewery.nameили простоbrewery?