Vipul Sinha
Vipul Sinha

Reputation: 840

TypeError: Cannot read property 'state' of undefined. Updated React

I'm very new to react so I'm just following youtube video but I got this error and I don't know anything about this. Terminal showing 'Compiled Successfully' but I'm getting this error. This is my App.js code

import Todos from './components/Todos';
import './App.css';

function App() {
  React.state = {
    todos: [
      {
        id: 1,
        title: 'Pay the rent',
        completed: false
      },
      {
        id: 2,
        title: 'Dinner at Pappu',
        completed: false
      },
      {
        id: 3,
        title: 'CODROBO Meeting',
        completed: false
      }
    ]
  };
  return (
    <div className='App'>
      <Todos todos={this.state.todos} />
    </div>
  );
}

export default App;

and this is my Todos.js code


function Todos() {
  return this.props.todos.map(todo => <h3> {todo.title} </h3>);
}

export default Todos;

According to video lecture browser must be showing all the todos but I'm getting this error

Upvotes: 1

Views: 349

Answers (5)

Sodnarts
Sodnarts

Reputation: 371

You are using a functional component, whilst using the syntax of a class component for state. This will not work.

There is two options for fixing this:

First one would be the easiest since most of your code is written with class component syntax -- Change it to a class component.

class App extends React.Component {
  state = {
    todos: [
      {
        id: 1,
        title: 'Pay the rent',
        completed: false
      },
      {
        id: 2,
        title: 'Dinner at Pappu',
        completed: false
      },
      {
        id: 3,
        title: 'CODROBO Meeting',
        completed: false
      }
    ]
  };

   render() {
      return (
         <div className='App'>
             <Todos todos={this.state.todos} />
         </div>
      );
   }
}

export default App;

Or you can change the state to the one of a functional component:

App.js

import Todos from './components/Todos';
import './App.css';

function App() {
  const [todos, setTodos] = React.useState([
      {
        id: 1,
        title: 'Pay the rent',
        completed: false
      },
      {
        id: 2,
        title: 'Dinner at Pappu',
        completed: false
      },
      {
        id: 3,
        title: 'CODROBO Meeting',
        completed: false
      }
    ])
  return (
    <div className='App'>
      <Todos todos={todos} />
    </div>
  );
}
export default App;

Todos.js

function Todos({todos}) {
  return todos.map(todo => <h3> {todo.title} </h3>);
}

export default Todos;

Using these two above files should resolve your issue completely.

Upvotes: 2

Ryan Pace
Ryan Pace

Reputation: 27

from your program, there seems to be a slight error in the writing state. you can see in my example down below or in here. I hope this helps :)

// App.js
import React, { useState } from "react";
import Todos from "./Todos";

export default function App() {
  const [todos] = useState([
    {
      id: 1,
      title: "Pay the rent",
      completed: false
    },
    {
      id: 2,
      title: "Dinner at Pappu",
      completed: false
    },
    {
      id: 3,
      title: "CODROBO Meeting",
      completed: false
    }
  ]);
  return (
    <div className="App">
      <Todos todos={todos} />
    </div>
  );
}

// Todos.js
import React from "react";

function Todos({ todos }) {
  return (
    <React.Fragment>
      {todos.map((item, i) => (
        <div
          style={{
            background: "blue",
            margin: "10px",
            padding: "10px",
            color: "white"
          }}
          key={i}
        >
          <p
            style={{
              background: "red",
              width: "18px",
              borderRadius: "50%",
              padding: "5px"
            }}
          >
            {item.id}
          </p>
          <h3>{item.title}</h3>
        </div>
      ))}
    </React.Fragment>
  );
}

export default Todos;

Upvotes: 1

Rojen
Rojen

Reputation: 346

As @Akhil Aravind pointed out you are trying to access this in functional component, which is the property of class. Try this:

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

class App extends Component {
  state = {
    todos: [
      {
        id: 1,
        title: 'Pay the rent',
        completed: false
      },
      {
        id: 2,
        title: 'Dinner at Pappu',
        completed: false
      },
      {
        id: 3,
        title: 'CODROBO Meeting',
        completed: false
      }
    ]
  };
render(){
return (
    <div className='App'>
      <Todos todos={this.state.todos} />
    </div>
  );
}

}

export default App;

function Todos(props) {
  return props.todos.map(todo => <h3> {todo.title} </h3>);
}

export default Todos;

Hope this solves.

Upvotes: 2

akhtarvahid
akhtarvahid

Reputation: 9769

Either you pass props or directly use destructuring.

// using props if it's functional component
function Todos(props) {
  return props.todos.map(todo => <h3> {todo.title} </h3>);
}

or

// using destructuring
   function Todos({todos}) {
    return todos.map(todo => <h3> {todo.title} </h3>);
  }

if it's functional component use props.todos. if class based component use this.props.todos

As i can see - you need to define hooks or class based component to define state

// Hooks
function App() {
  const [todos, setTodos] = React.useState([
      {
        id: 1,
        title: 'Pay the rent',
        completed: false
      },
      {
        id: 2,
        title: 'Dinner at Pappu',
        completed: false
      },
      {
        id: 3,
        title: 'CODROBO Meeting',
        completed: false
      }
    ])
  return (
    <div className='App'>
      <Todos todos={todos} />
    </div>
  );
}

Class based

class App extends React.Component {
  state = {
    todos: [
      {
        id: 1,
        title: "Pay the rent",
        completed: false
      },
      {
        id: 2,
        title: "Dinner at Pappu",
        completed: false
      },
      {
        id: 3,
        title: "CODROBO Meeting",
        completed: false
      }
    ]
  };
  render() {
    return (
      <div className="App">
        {this.state.todos.map(todo => (
          <h3>{todo.title}</h3>
        ))}
      </div>
    );
  }
}

Upvotes: 1

user10070377
user10070377

Reputation:

In your Todos function you need to have your props from App and also since Todos is is a functional component, you don't need to use this keyword

function Todos(props) {
      return props.todos.map(todo => <h3> {todo.title} </h3>);
    }
    
    export default Todos;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Upvotes: 0

Related Questions