Lifting State Up with Functional Components

Viewed 3694

I'm trying to lift the state of the input in AddTodo.js to my App.js.

I'm getting the next error : "TypeError: Cannot read property 'preventDefault' of undefined".

I've tried many variations and looking online just confuses me more (I do manage to call a parent function from a child function, but i can't seem to pass the input data to the onAddHandler)

Help appreciated!

App.js :

import React, { useState } from "react";
import Header from "./UI/Header";
import TodoList from "./Components/TodoList";
import AddTodo from "./Components/AddTodo";

function App(props) {
  const [todo, setTodo] = useState([]);

  const onAddHandler = (input, e) => {
    e.preventDefault();
    setTodo([
      ...todo,
      {
        name: input,
      },
    ]);
    console.log(input);
  };

  return (
    <div>
      <div className="App">
        <AddTodo onAddHandler={onAddHandler} />
        <Header />
        <TodoList />
      </div>
    </div>
  );
}

export default App;

AddTodo.js :

import React, { useState } from "react";

const AddUser = ({ onAddHandler }) => {
  const [input, setInput] = useState("");

  const inputChangeHandler = (e) => {
    setInput(e.target.value);
  };

  return (
    <div>
      <form onSubmit={onAddHandler(input)}>
        <input id="todoname" type="text" onChange={inputChangeHandler}></input>
        <button type="submit">Submit</button>
      </form>
    </div>
  );
};

export default AddUser;
2 Answers

You should add a callback to onClick event for the button submit:

import React, { useState } from "react";

const AddUser = ({ onAddHandler }) => {
  const [input, setInput] = useState("");

  const inputChangeHandler = (e) => {
    setInput(e.target.value);
  };

  return (
    <div>
      <form onSubmit={onAddHandler(input)}>
        <input id="todoname" type="text" onChange={inputChangeHandler}></input> //change this line
        <button type="submit" onClick={(e) => onAddHandler(input, e)}>Submit</button>
      </form>
    </div>
  );
};

I think you should pass eventHandlers to your AddTodo component along with state value, and get useState() in App component. Your AddTodo.js only get these handlers and values as props.

Related