Actualmente estoy aprendiendo gancho y estoy escribiendo una lista de tareas pendientes:
import './App.css'; import React, {useState} from 'react'; import Item from './components/Item'; function App() { const [tasks, setTasks] = useState([]); const addTask = (e) => { if(e.key === 'Enter'){ let newTask = {content: e.target.value, completed: false}; console.log(newTask); setTasks(prevTask => { return ([...prevTask, newTask]); }); console.log(tasks); } } const completeTask = (e) =>{ let newTask = tasks.slice(); newTask[e].completed = !tasks[e].completed; setTasks(newTask); } const deleteTask = (e) => { let newTask = tasks.slice(); newTask.splice(e); setTasks(newTask); } return ( <> <header className="todo-app__header"> <h1 className="todo-app__title">todos</h1> </header> <section className="todo-app__main"> <input className="todo-app__input" placeholder="What needs to be done?" onKeyDown={addTask}/> <ul className="todo-app__list" id="todo-list"> {tasks.map(item => <Item num = {tasks.indexOf(item)} text={item.content} completed = {item.completed} onClick = {completeTask(tasks.indexOf(item))} delete = {deleteTask(tasks.indexOf(item))}/>)} </ul> </section> </> ); } export default App;Sin embargo, ¡agregar tareas no funciona! La nueva tarea impresa está bien, pero no se inserta en la matriz de tareas. Las tareas aún están vacías.
¿Cuál es el problema? Además, otro problema: ¿está relacionado con useeffect ? No sé para qué se usa useeffect .
El problema es que cada vez que su componente se procesa, ejecuta completeTask y deleteTask , porque está utilizando llamadas a funciones como accesorios. Debe pasar un objeto de función o una expresión. En lugar de decirle al componente que ejecute completeTask al hacer clic, la llamada a la función simplemente lo ejecuta allí mismo tan pronto como se procesa el componente.
El problema está en esta parte de tu código:
<ul className="todo-app__list" id="todo-list"> {tasks.map(item => <Item num = {tasks.indexOf(item)} text={item.content} completed = {item.completed} onClick = {completeTask(tasks.indexOf(item))} delete = {deleteTask(tasks.indexOf(item))}/>)} </ul>Las siguientes lineas:
delete = {deleteTask(tasks.indexOf(item))} onClick = {completeTask(tasks.indexOf(item))}Debería cambiarse a:
delete = {() => deleteTask(tasks.indexOf(item))} onClick = {() => completeTask(tasks.indexOf(item))} En HTML normal, se vería como delete="deleteFunction()" , pero en React, debería ser delete={deleteFunction} , porque escribir una función con paréntesis después es una llamada de función, no una expresión de función. Si necesita pasar un argumento, puede pasar el argumento como accesorio en el componente o cambiar la línea a delete={() => deleteFunction(arg)} , ya que el paréntesis y la flecha lo convierten en una función expresión.
Consulte Manejo de eventos: https://reactjs.org/docs/handling-events.html
Su código funciona bien y no hay problema.
Reacciona la acción setState de forma asíncrona. Intente iniciar sesión en useEffect .
const App = () = => { const [tasks, setTasks] = useState([]); useEffect(() => { console.log(tasks) }, [tasks]); const addTask = () => { const newTask = {...}; setTasks([...tasks, newTask]); } }Aquí, como puedo ver, está haciendo console.log(tasks) en la misma función. Pruebe la función externa console.log(tasks) y verá una matriz de tasks con los valores que ingresó.