Why isn't my child component receiving props?

Why isn't my child component receiving props?
0.0 0

#1

Ok so I wrote a simple React app for the first time ever and I want to split it into components, so I made a Cockpit component for the input textarea and a list component for rendering the results, which are contained inside my App.js. I’m getting the following error:

TypeError: Cannot read property 'userInput' of undefined
cockpit

> 17 |   value={props.state.userInput}

I don’t know what I’m doing wrong and I’m just trying to wrap my head around how components interact so I’m sorry if this is a silly question. But could you have a look and tell me what’s my mistake?
Here’s my code:

App.js:

import React, { Component } from 'react';
import Cockpit from './Cockpit/Cockpit';
import './App.css';


class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      userInput : '',
      listItems : []
    }
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleSubmit() {
    const itemsArr = this.state.userInput.split(',');
    this.setState({ 
      listItems: itemsArr
    });
  }

  handleChange (event) {
    this.setState({
      userInput: event.target.value
     });   
  }

  
  render() {
    
    return (
      <div className="App">
      <Cockpit 
        clicked={this.handleSubmit}
        changed={this.handleChange}/>
      </div>
    );
  }
}

export default App;

Cockpit.js:

import React from 'react';
import List from '../List/List';


const cockpit = (props) => {
    return (
        <div>
        <header className="App-header">
        This is a header
        <h1 className="App-title">To-Do Lists</h1>
        </header>
        <p className="App-intro">
          So here should be an explanation of how this works.
        </p>
        <textarea 
          changed={() => props.handleChange()}
          value={props.state.userInput}
          placeholder="Separate items with commas"
        />
        <button 
           clicked={() => props.handleSubmit()}>
           Create List
        </button>
           <ul className="Results">
             <List 
               listItems = {this.state.listItems}/>
            </ul>
         </div>
    )};

    export default cockpit;

List.js:

import React from 'react';

const list = (props) => props.listItems.map(function(item){
        return <li>{item}</li>;
      });

export default list;

Thanks so much in advance!! :pray:


#2

It should just come in as `props.userInput* for a functional component (as you have here) or this.props.userInput if it were a class component. There is no need for the property state for a prop - it’s one or the other, either local state or a passed in prop.


#3

Great! Solved that.
But I’m still getting:

TypeError: Cannot read property ‘map’ of undefined
list

3 | const list = (props) => props.listItems.map(function(item){

why is that?isn’t listItems passed as props?


#4

This is in your Cockpit component.

<List listItems = {this.state.listItems}/>

But

  1. that component is a functional component so it can’t have state
  2. you have not passed in the state to the cockpit as a prop, so it can’t forward it.
<Cockpit 
  listItems={this.state.listItems} // this should be added here
  clicked={this.handleSubmit}
  changed={this.handleChange}
/>

#5

Ooohhh thanks so much!!! Now I get it!! :grin::grin::grin: