I am new to react js and I am trying to create a todo list app.
I use a modal to get two user inputs(Task Name and Description) from CreateTask component and pass those user input as an object to the TodoList component. Then I tried to update the state and display the list. But it always shows as empty.
Please if someone helps me to solve this, I really thankful.
This is my code.
TodoList function Component
import React, { useState, Fragment } from 'react'
import CreateTask from './modals/CreateTask'
const TodoList = () => {
const[modal,setModal] = useState(false);
const[taskList, setTaskList] = useState([]);
const toggle = () =>{
setModal(!modal);
}
//saveTask function to update the taskList state
const saveTask = function (taskOBJ){
let arr = taskList.concat(taskOBJ);
setTaskList(...taskList, arr);
setModal(false);
console.log(arr) // arr displays Name and Description values correctly in the console
}
return (
<Fragment>
<div className='header text-center'>
<h1>Todo List</h1>
<button className='btn btn-primary mt-2' onClick={()=>{setModal(true)}} >Create a Task</button>
</div>
<div className='task-container'>
//Displaying the task name here.
{ taskList.map((list)=> {
<li>{list.Name}</li>
})
}
</div>
<CreateTask modal={modal} toggle={toggle} save={saveTask}/>
</Fragment>
)
}
export default TodoList
This is the CreateTask Function Component
import React, { useState } from 'react'
import {Button, Modal, ModalBody, ModalHeader, ModalFooter} from 'reactstrap';
const CreateTask = ({modal, toggle, save}) => {
const[taskName, setTaskName] = useState("");
const[description, setDescription] = useState("");
// FUNCTION handleChange
const handleChange = (e)=>{
const{name, value} = e.target;
if(name === "taskName"){
setTaskName(value);
}else{
setDescription(value);
}
}
// FUNCTION handleSave
const handleSave = ()=>{
let taskObject ={}
taskObject.Name = taskName;
taskObject.Description = description;
save(taskObject);
// console.log(taskObject)
}
return (
<div>
<Modal
isOpen={modal}
toggle={toggle}
// animation={false}
>
<ModalHeader toggle={toggle}>
Create Task
</ModalHeader>
<ModalBody>
<form>
<div className='form-group'>
<label>Task Name</label>
<input type="text" className='form-control' name="taskName" value ={taskName} onChange ={handleChange}/>
</div>
<div className='form-group mt-4'>
<label>Description</label>
<textarea className='form-control' name="description" value={description} onChange ={handleChange}/>
</div>
</form>
</ModalBody>
<ModalFooter>
// BUTTON which is associate with FUNCTION handleSave
<Button
color="primary"
onClick={handleSave}
>
Create
</Button>
{' '}
<Button onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
)
}
export default CreateTask
CodePudding user response:
Your todos are not rendering because you are not returning anything from the iterated array,
{taskList.map((list)=> {
<li>{list.Name}</li>
})}
// Should be
{taskList.map((list)=> {
return <li>{list.Name}</li>
})}
// Or
{taskList.map((list)=> <li>{list.Name}</li>)}
Also, your saveTask
should manage the state like so,
const saveTask = function (taskOBJ) {
// Since your state is an array,
// you can't spread the current state array into the updating function.
// setTaskList(...taskList, arr)
// Here you take the `prev` state, and return a new array that
// contains a spread of `prev` and the new task.
setTaskList((prev) => [...prev, taskOBJ]);
setModal(false);
// Another way of achieving the same could be
const newTaskList = [...taskList, taskObj];
setTaskList(newTaskList);
setModal(false);
};
CodePudding user response:
Change saveTask to this:
const saveTask = function (taskOBJ){
setTaskList([...taskList, taskOBJ]);
setModal(false);
}