Genjik
Genjik

Reputation: 329

pass object from state as props to child component

I am creating weather app with React and I have an api which provides me object

import React, { Component } from 'react';
import WeeklyWeather from './components/WeeklyWeather';
const api = '';
class App extends Component {
  constructor() {
    super();
    this.state = {
      weather: {}
    }
  }

  componentDidMount() {
    fetch(api)
    .then(response => response.json())
    .then(data => this.setState({ weather: data }));
  }

  render() {
    return (
      <div className="App">
        <WeeklyWeather day={this.state.weather.daily.data} />
      </div>
    );
  }
}

After fetching it, I store data as state. Finally, I want to pass this.state.weather.daily.data as props to child component, but I received TypeError: Cannot read property 'data' of undefined

Upvotes: 2

Views: 2456

Answers (3)

Elan Hamburger
Elan Hamburger

Reputation: 2177

You're passing the prop to the child before it exists.

componentDidMount() is called once the HTML is bound to the DOM, which means your render() has already run. But, of course, your render() refers to this.state.weather.daily.data which doesn't exist until after componentDidMount() completes.

All you have to do is check that the data is loaded before you attempt to use it.

<WeeklyWeather day={this.state.weather.daily && this.state.weather.daily.data} />

Upvotes: 1

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

    <WeeklyWeather day={this.state.weather.daily.data} />

It can be you get the error because before the async request has finished, there is no this.state.weather.daily initialized. Quick hack could be something like this:

  {   this.state.weather.daily && <WeeklyWeather day={this.state.weather.daily.data} />}

This will make sure WeeklyWeather is only rendered when daily is initialized.

Upvotes: 3

Naor Tedgi
Naor Tedgi

Reputation: 5699

the first render this.state.weather isn't initialized yet

follow this thread React state data null for the first time

   class App extends Component {
      constructor () {
        super()
        this.state = {
          weather: {}
        }
      }

      componentDidMount () {
        fetch(proxy)
          .then(response => response.json())
          .then(data => this.setState({ weather: data }))
      }

      render () {
        return (
          <div className='App'>
            {this.state.weather && (
              <WeeklyWeather day={this.state.weather.daily.data} />
            )}
          </div>
        )
      }
    }

Upvotes: 1

Related Questions