How can I edit a todo list on the same input where add todo in React?

28 Views Asked by At

I'm a begginer in React js, I have the code of a project taken from YouTube, the issue is that when I edit a task, I want to edit it in the same input where I add the tasks.

Actually I have no idea how to achieve this, I wish someone could help me

Here I got the main component: `import React from 'react'; import './App.css'; import TodoList from './components/TodoList';

function App() {
  return (
    <div className='todo-app'>
      <TodoList />
    </div>
  );
}

export default App;`


     Todo.jsx component:
`import React, { useState } from "react";
import { RiCloseCircleLine } from "react-icons/ri";
import { TiEdit } from "react-icons/ti";
import TodoForm from "./TodoForm";

const Todo = ({ todos, updateTodo, completeTodo }) => {
  const [edit, setEdit] = useState({
    id: null,
    value: "",
  });

  function updateSubmit(value) {
    updateTodo(edit.id, value);
    setEdit({
      id: null,
      value: "",
    });
  }

  if (editar.id) {
    return <TodoForm edit={edit} onSubmit={updateSubmit} />;
  }

  return todos.map((todo, index) => (
    <div
      className={todo.isComplete ? "todo-row complete" : "todo-row"}
      key={index}
    >
      <div key={todo.id} onClick={() => completeTodo(todo.id)}>
        {todo.text}
      </div>
      <div className="icons">
        <TiEdit
          onClick={() => setEdit({ id: todo.id, value: todo.text })}
          className="edit-icon"
        />
      </div>
    </div>
  ));
};

export default Todo;`


TodoList.jsx component:
`import React, { useState } from "react";
import TodoForm from "./TodoForm";
import Todo from "./Todo";

function TodoList() {
  const [todos, setTodos] = useState([]);

   const addTodo = (todo) => {
     const newTodos = [todo, ...todos];

    setTodos(newTodos);
  };

  const updateTodo = (todoId, newValue) => {
    if (!newValue.text || /^\s*$/.test(newValue.text)) {
      return;
    }

    setTodos((prev) =>
      prev.map((item) => (item.id === todoId ? newValue : item))
    );
  };

  const completeTodo = (id) => {
    let updatedTodos = todos.map((todo) => {
      if (todo.id === id) {
        todo.isComplete = !todo.isComplete;
      }
      return todo;
    });
    setTodos(updatedTodos);
  };

  return (
    <React.Fragment>
      <h1>What's the Plan for Today?</h1>
      <TodoForm onSubmit={addTodo} />

      <Todo
        todos={todos}
        completeTodo={completeTodo}
        updateTodo={updateTodo}
      />
    </React.Fragment>
  );
}

export default TodoList;`


 TodoForm component:
`import React, { useState, useEffect, useRef } from "react";

function TodoForm({ edit, onSubmit }) {
  const [input, setInput] = useState(edit ? edit.value : "");

  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
  });

  const handleChange = () => {
    setInput(inputRef.current.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    if (!inputRef.current.value || /^\s*$/.test(inputRef.current.value)) {
      return;
    }

    onSubmit({
      id: Math.floor(Math.random() * 10000),
      text: inputRef.current.value,
    });
    setInput("");
  };

  return (
    <form onSubmit={handleSubmit} className="todo-form">
      <React.Fragment>
        <input
          placeholder={edit ? "Update your item" : "Add a Todo"}
          value={input}
          onChange={handleChange}
          name="text"
          className={edit ? "todo-input edit" : "todo-input"}
          ref={inputRef}
        />
        <button
          onClick={handleSubmit}
          className={edit ? "todo-button edit" : "todo-button"}
        >
          Update
        </button>
      </React.Fragment>
    </form>
  );
}

export default TodoForm;
`

       

[edit task in another input](https://i.stack.imgur.com/ajma4.png)

[different input](https://i.stack.imgur.com/52R2k.png) 
1

There are 1 best solutions below

0
Rの卄IT On

In Todo and TodoForm component, editar which doesn't exist. This should be changed to edit. There is also an issue where edit may not be passed to TodoForm correctly in the Todo component.

import React, { useState, useEffect, useRef } from 'react';
import { TiEdit } from 'react-icons/ti';

// TODO
const Todo = ({ todos, updateTodo, completeTodo }) => {
  const [edit, setEdit] = useState({
    id: null,
    value: '',
  });

  function updateSubmit(value) {
    updateTodo(edit.id, value);
    setEdit({
      id: null,
      value: '',
    });
  }

  if (edit.id) {
    return <TodoForm edit={edit} onSubmit={updateSubmit} />;
  }

  return todos.map((todo, index) => (
    <div
      className={todo.isComplete ? 'todo-row complete' : 'todo-row'}
      key={index}
    >
      <div key={todo.id} onClick={() => completeTodo(todo.id)}>
        {todo.text}
      </div>
      <div className="icons">
        <TiEdit
          onClick={() => setEdit({ id: todo.id, value: todo.text })}
          className="edit-icon"
        />
      </div>
    </div>
  ));
};

// TODOLIST
function TodoList() {
  const [todos, setTodos] = useState([]);

  const addTodo = (todo) => {
    const newTodos = [todo, ...todos];

    setTodos(newTodos);
  };

  const updateTodo = (todoId, newValue) => {
    if (!newValue.text || /^\s*$/.test(newValue.text)) {
      return;
    }

    setTodos((prev) =>
      prev.map((item) => (item.id === todoId ? newValue : item))
    );
  };

  const completeTodo = (id) => {
    let updatedTodos = todos.map((todo) => {
      if (todo.id === id) {
        todo.isComplete = !todo.isComplete;
      }
      return todo;
    });
    setTodos(updatedTodos);
  };

  return (
    <React.Fragment>
      <h1>What's the Plan for Today?</h1>
      <TodoForm onSubmit={addTodo} />

      <Todo todos={todos} completeTodo={completeTodo} updateTodo={updateTodo} />
    </React.Fragment>
  );
}

// TODFORM
function TodoForm({ edit, onSubmit }) {
  const [input, setInput] = useState(edit ? edit.value : '');

  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
  });

  const handleChange = () => {
    setInput(inputRef.current.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    if (!inputRef.current.value || /^\s*$/.test(inputRef.current.value)) {
      return;
    }

    onSubmit({
      id: Math.floor(Math.random() * 10000),
      text: inputRef.current.value,
    });
    setInput('');
  };

  return (
    <form onSubmit={handleSubmit} className="todo-form">
      <React.Fragment>
        <input
          placeholder={edit ? 'Update your elemento' : 'Add a Todo'}
          value={input}
          onChange={handleChange}
          name="text"
          className={edit ? 'todo-input edit' : 'todo-input'}
          ref={inputRef}
        />
        <button
          onClick={handleSubmit}
          className={edit ? 'todo-button edit' : 'todo-button'}
        >
          Update
        </button>
      </React.Fragment>
    </form>
  );
}

const styles = {
  app: {
    background: '#eee',
    padding: 20,
    maxWidth: 500,
    margin: '0 auto',
  },
};

function App() {
  return (
    <div style={styles.app}>
      <TodoList />
    </div>
  );
}

export default App;

Here is the live Stackblitz