Home > Enterprise >  update the state in React JS array using useSatate
update the state in React JS array using useSatate

Time:03-30

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);

}
  • Related