Need JS+React help in the wilderness beyond FCC

I am getting stuck at a very fundamental stage of React, i.e. sending data (that I pulled from a file opened/read in a parent component) down to a child component via props.

Based on console.log debugging, it looks like props is empty. But I don’t understand why?

It’s been a while since I was hands-on with React so I feel like I’m just forgetting some basic principle and will feel silly once someone points it out to me.

My code so far:

import React, { Component } from "react";
import VicAreaChart from "./vicAreaChart";

class DataParser extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
    this.updateData = this.updateData.bind(this);
  }

  componentWillMount() {
    // Your parse code, but not seperated in a function
    var csvFilePath = require("../data/household_characteristics.csv");
    var Papa = require("papaparse/papaparse.min.js");
    Papa.parse(csvFilePath, {
      header: true,
      download: true,
      skipEmptyLines: true,
      // Here this is also available. So we can call our custom class method
      complete: this.updateData
    });
  }

  updateData(result) {
    const data = result.data;
    // Here this is available and we can call this.setState (since it's binded in the constructor)
    this.setState({ data: data }); // or shorter ES syntax: this.setState({ data });
  }

  render() {
    const { data } = this.state;

    // Your render function
    console.log(data[0]);
    console.log(data[1]);
    return (
      <div>
        <p>Data</p>
        <VicAreaChart />
      </div>
    );
  }
}

export default DataParser;

and:

import React from "react";

const VicAreaChart = props => {
  console.log(props);
  // console.log(props[0]["survey"]);
  // console.log(Object.values(props));
  return <p>This is not a drill</p>;
};

export default VicAreaChart;

You are not passing any prop to VicAreaChart component.

<VicAreaChart />

Perhaps something like:

<VicAreaChart  myAwesomeData={this.state.data}/>

Remember that at the core React components are just functions, you need to pass any argument you want your function to use. :slight_smile:

Also side note:

1- React has an amazing extension for browser to help you debug your program, you’ll see it’s by far easier that logging props in console

2 - componentWillMount will be deprecated in the next versions of React and is now considered legacy. You can see on the official doc that it has been renamed to UNSAFE_componentWillMount().

Regardless of that you should avoid any side effect at this time.
If you need to fetch some data is better to it during componentDidMount()

Hope it helps :+1:

1 Like

Thanks @Marmiz!

I have another question. When I send the data over as props, I thought I was sending an array of objects like this:

I wanted to iterate over the first few elements of this array to create a JSX element for each. But I keep getting this error:
Objects are not valid as a React child

But I don’t understand why it thinks that…

According to my debugging, it is an array:

Also, when I console logged the data in parent component, it let me reference the first element using an index, i.e. this.state.data[0].

I tried to read some of the stackOverflow docs but one of them described what to do in case you are using TypeScript and another said to reference the property instead…but that didn’t work either, i.e. referencing the props[“key”].

Can anyone help!!

It’s hard to tell without seeing your code.

React can output that error also when you are looping and rendering something that is not allowed.
This usually means there’s an error in your loop.

Make sure you are using a valid method (in general map) to create a proper markup, something like

<div>
{
 this.props.data.map(el => <p>{el.id}</p>)
}
</div>

Also: are you sure you are passing the props? Looking at the inspector screenshot is hard to tell, and yet there’s no reference to any prop on <VicAreaChart />

I would expect to see something like:

<VicAreaChart  foo={bar} />

OMG…I promise you I was doing exactly what you had but it wasn’t working before. Data is pulling fine now. Ugh. Annoyed with myself. Thank you @Marmiz!

Final code (at this stage) in case anyone cares:

import React, { Component } from "react";
import VicAreaChart from "./vicAreaChart";

class DataParser extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
    this.updateData = this.updateData.bind(this);
  }

  componentDidMount() {
    // Your parse code, but not seperated in a function
    var csvFilePath = require("../data/household_characteristics.csv");
    var Papa = require("papaparse/papaparse.min.js");
    Papa.parse(csvFilePath, {
      header: true,
      download: true,
      skipEmptyLines: true,
      // Here this is also available. So we can call our custom class method
      complete: this.updateData
    });
  }

  updateData(result) {
    const data = result.data;
    // Here this is available and we can call this.setState (since it's binded in the constructor)
    this.setState({ data: data }); // or shorter ES syntax: this.setState({ data });
  }

  render() {
    // Your render function
    console.log(this.state.data);
    return (
      <div>
        <VicAreaChart hhData={this.state.data} />
      </div>
    );
  }
}

export default DataParser;

and:

import React from "react";

const VicAreaChart = props => {
  const hhData = props.hhData;
  console.log(hhData);
  return (
    <div>
      <p>This is not a drill</p>
      {hhData.map(el => (
        <p key={el.hhid}>{el.survey}</p>
      ))}
    </div>
  );
};

export default VicAreaChart;