Props turns out to be undefined in Reactjs

Viewed 1903

Hi I was trying to setState for my app based on the values of Props I was relying on values of prop for my state , But when I passed the function to setState the props I received were undefined , don't know why , I followed this document for reference. You can read the section that says State Updates May Be Asynchronous Below is my code (code snippet from File Form.js)

this.props.setTodos(function (_, props) {
      console.log("this is props:" + props);
      return [
        ...props.todos,
        { text: props.inputText, completed: false, id: Math.random() *            1000 },
      ];
    });

Code for App.js File where I pass props

import "./App.css";
import Form from "./components/Form";
import TodoList from "./components/TodoList";
import React, { useState } from "react";
function App() {
  const [inputText, setText] = useState("");
  const [todos, setTodos] = useState([]);
  return (
    <div className="App">
      <header>
        <h1>My Todolist </h1>
      </header>
      <Form
        todos={todos}
        setTodos={setTodos}
        setText={setText}
        inputText={inputText}
      />
      <TodoList />
    </div>
  );
}

export default App;

Full code for Form.js file

import React from "react";

class Form extends React.Component {
  constructor(props) {
    super(props);
  }
  handler = (e) => {
    // console.log(e.target.value);
    this.props.setText(e.target.value);
  };
  submitTodoHandler = (e) => {
    e.preventDefault();

    this.props.setTodos(function (_, props) {
      console.log("this is props:" + props);
      return [
        ...props.todos,
        { text: props.inputText, completed: false, id: Math.random() * 1000 },
      ];
    });
  };
  render() {
    return (
      <div>
        <form>
          <input onChange={this.handler} type="text" className="todo-input" />
          <button
            onClick={this.submitTodoHandler}
            className="todo-button"
            type="submit"
          >
            <i className="fas fa-plus-square"></i>
          </button>
          <div className="select">
            <select name="todos" className="filter-todo">
              <option value="all">All</option>
              <option value="completed">Completed</option>
              <option value="uncompleted">Uncompleted</option>
            </select>
          </div>
        </form>
      </div>
    );
  }
}
export default Form;

I don't know why my props are undefined ? Thanks

1 Answers

What you need to do is to change submitTodoHandler function in your <Form> component:

submitTodoHandler = (e) => {
    e.preventDefault();
    console.log(this.props.inputText) // outputs what you typed in the input
    this.props.setTodos(this.props.inputText);
  };

You define setState in functional component and pass it as a prop to class component. setState hook in functional components behaves slightly different from setState in class components, which you are referencing to.

In functional components setState (or setTodos in your case) changes the state of the variable simply by using setState(newVariableValue) and accepts as a parameter previous state. As newVariableValue is passed with a prop (inputText) from <App> component to <Form> component, you can directly access it with this.props.inputText.

Using the State Hook

Related