«TypeErroe: невозможно прочитать свойство NAME of undefined» после попытки извлечь ключ / значение из вложенного объекта - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь получить некоторые данные в react-native, где храню извлеченные данные в переменной state, чтобы я мог получить к ним доступ в любом месте компонента.Это код:

export default class Result extends Component {
    state = {
        data: {}
    };

    async componentDidMount() {
        const that = this;
        const url = 'https://world.openfoodfacts.org/api/v0/product/8002270014901.json';
        let response = await fetch(url);
        if (response.status == 200) {
            let data = await response.json();
            this.setState({ data });
        }
    }

    ... some code ...

    render() {
      console.log(this.state.data.product);

    ...some more code ...
    }
}

Я получил код из componentDidMount из другой статьи SOF, чтобы убедиться, что у меня есть data, с которым я могу работать.Когда я пытаюсь проверить результат, он отлично работает с console.log, который вы видите в коде.Но если я попытаюсь пройти на один уровень глубже внутри объекта (например, console.log(this.state.data.product.brands);, я получу сообщение об ошибке, упомянутое в теме. Почему это так? Как мне убедиться, что весь объект «загружен», прежде чем я продолжу работу?

1 Ответ

0 голосов
/ 26 февраля 2019

В данном случае мне приходит в голову, что вы получаете ответ после выполнения метода render.

Вы можете спросить Но как это работает, когда я регистрирую только this.state.data.product?
Что ж, когда вы инициализируете свое состояние, вы определяете, что у него есть объект data, поэтомув этом случае код не будет нарушен, потому что this.state.data.product равен undefined, но когда вы пытаетесь получить еще один слой глубже, вы пытаетесь получить доступ к свойству со значением undefined, что приводит к ошибкеполучение (не может прочитать свойство x из неопределенного).

Итак, что я могу сделать, чтобы это исправить?

Вы должны хранить логическую переменную в своем состоянии, давайтеназовите его fetchingData и присвойте ему значение по умолчанию true, так что теперь у вас есть

state = {
  data: {},
  fetchingData: true
};

, а затем в вашем методе render вы проверяете, извлекает ли он данные или ужеответ от сервера, измените его так, чтобы он был таким:

render() {
  if(this.state.fetchingData) return <View><Text>Fetching data...</Text></View>
  console.log(this.state.data.product.brands);
  return(
    Whatever you want to do with the data...
  )
}

Что происходит, когда вы все еще ждете данных, будет отображаться сообщение Fetching data..., теперь, когда вы получите данные, которые вытакже необходимо изменить fetchingData на false.

if (response.status == 200) {
  let data = await response.json();
  this.setState({
    data: data,
    fetchingData: false
  });
}
...