Search code examples
reactjsreact-hooks

Cannot read properties of undefined (reading 'value'). I am trying to build a todo app using react js


Cannot read properties of undefined (reading 'value'). I am facing this error and not finding a way to fix it. I am trying to build a todo app using react js. Below is the app.js code...

import "./App.css";

function App() {
  const [inputValue, setInputValue] = useState("");
  const [addTodo, setAddTodo] = useState([]);

  console.log(inputValue);
  return (
    <div classNameName="screen-background-color">
      <div className="app-content-background">
        <div className="todo-list-heading">
          <h1>To-Do List</h1>
          <img className="todo-image-styles" src="./images/icon.png" alt="" />
        </div>
        <div className="input-and-btn-styles">
          <input
            value={inputValue}
            onChange={setInputValue((e) => e.target.value)}
            className="input"
            type="text"
            placeholder="Add Your Task"
          />
          <button onClick={setAddTodo(inputValue)} className="add-btn">
            Add
          </button>
        </div>
        <div className="unchecked-image-and-text">
          <img
            className="unchecked-image"
            src="./images/unchecked.png"
            alt=""
          />
          <h4 className="unchecked-h5-heading">{addTodo}</h4>
        </div>
      </div>
    </div>
  );
}

export default App;

Solution

  • you're incorrectly setting the onChange handler. The correct syntax is to pass a function that updates the state based on the event. You've currently passed the result of setInputValue((e) => e.target.value) directly to onChange, which is incorrect. Similarly, in your button component, you're directly calling setAddTodo(inputValue) in the onClick handler, which is also incorrect.

    import { useState } from "react";
    import "./App.css";
    
    function App() {
      const [inputValue, setInputValue] = useState("");
      const [todos, setTodos] = useState([]);
    
      const handleInputChange = (e) => {
        setInputValue(e.target.value);
      };
    
      const handleAddTodo = () => {
        if (inputValue.trim() !== "") {
          setTodos([...todos, inputValue]);
          setInputValue(""); // Clear input after adding todo
        }
      };
    
      console.log(todos);
    
      return (
        <div className="screen-background-color">
          <div className="app-content-background">
            <div className="todo-list-heading">
              <h1>To-Do List</h1>
              {/* Replace with correct path to your image */}
              <img className="todo-image-styles" src="./images/icon.png" alt="" />
            </div>
            <div className="input-and-btn-styles">
              <input
                value={inputValue}
                onChange={handleInputChange}
                className="input"
                type="text"
                placeholder="Add Your Task"
              />
              <button onClick={handleAddTodo} className="add-btn">
                Add
              </button>
            </div>
            <div className="unchecked-image-and-text">
              <img
                className="unchecked-image"
                src="./images/unchecked.png"
                alt=""
              />
              {/* Display todos */}
              <ul>
                {todos.map((todo, index) => (
                  <li key={index} className="unchecked-h5-heading">
                    {todo}
                  </li>
                ))}
              </ul>
            </div>
          </div>
        </div>
      );
    }
    
    export default App;