React Native рендер вложенный Json - PullRequest
0 голосов
/ 04 июля 2018

После загрузки объекта JSON и добавления его в this.state я не могу получить доступ к уровням ниже первого уровня. Учитывая этот файл JSON:

{
  "ts": 1530703572,
  "trend": {
    "val": 0,
    "text": "gleichbleibend"
  },
  "baro": 1011.3453734999999,
  "temp": {
    "out": {
      "f": 85.9,
      "c": 29.9
    }
  },
  "hum": {
    "out": 28
  },
  "wind": {
    "speed": {
      "mph": 2,
      "kmh": 3.2
    },
    "avg": {
      "mph": 3,
      "kmh": 4.8
    },
    "dir": {
      "deg": 192,
      "text": "SSW"
    }
  },
  "rain": {
    "rate": 0,
    "storm": 0,
    "day": 0,
    "month": 0,
    "year": 451.358
  },
  "et": {
    "day": 88,
    "month": 81,
    "year": 1802
  },
  "forecast": {
    "val": 6,
    "rule": 45,
    "text": "Zunehmend wolkig bei gleichbleibender Temperatur."
  },
  "sun": {
    "uv": 6.2,
    "rad": 779,
    "rise": "4:27",
    "set": "20:35"
  }
}

следующие результаты:

  1. {this.state.weatherList.ts} работает: 1530703572
  2. {this.state.weatherList.temp.out.c} "Ошибка типа: Undefined не является объектом (оценка: 'this.state.weatherList.temp.out')

Код:

export default class Weather extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            weatherList: []
        }

        getPlannerData().then(data => {
            this.setState({
                weatherList: data
            })

        })
    }

        return (
            <ScrollView>
                <View>
                    <View>
                        <Text>{this.state.weatherList.temp.out.c}</Text>
                    </View>

                </View>
            </ScrollView>
        )
    }
}

async function getPlannerData() {
    let data = await fetchApi('url')
    return data
}

async function fetchApi(url) {
    try {
        let response = await fetch(url)
        let responseJson = await response.json()
        console.log(responseJson)
        return responseJson
    } catch (error) {
        console.error(error)
        return false
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 22
    },
    sectionHeader: {
        paddingTop: 2,
        paddingLeft: 10,
        paddingRight: 10,
        paddingBottom: 2,
        fontSize: 14,
        fontWeight: 'bold',
        backgroundColor: 'rgba(247,247,247,1.0)'
    },
    item: {
        padding: 10,
        fontSize: 18,
        height: 44
    }
})

Вопрос в том, как я могу изменить код, чтобы я мог получить доступ к вложенным элементам, таким как "temp".

Я пробовал это с renderItem и {this.state.weaetherList.map ((item, i) => без успеха.

Заранее спасибо!

1 Ответ

0 голосов
/ 04 июля 2018

До того, как ваш объект weatherList установлен, все, что ниже уровня вашего объекта, приведет к ошибке. this.state.weatherList.ts не выдаст ошибку, так как просто будет undefined до того, как ваш запрос будет завершен.

Вы можете, например, сохраняйте переменную состояния loading и выполняйте рендеринг только после завершения запроса, чтобы обойти это.

Пример

class Weather extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: true,
      weatherList: {}
    };

    getPlannerData().then(data => {
      this.setState({
        loading: false,
        weatherList: data
      });
    });
  }

  render() {
    const { loading, weatherList } = this.state;

    if (loading) {
      return null;
    }

    return (
      <ScrollView>
        <View>
          <View>
            <Text>{weatherList.temp.out.c}</Text>
          </View>
        </View>
      </ScrollView>
    );
  }
}
...