简体   繁体   中英

How to change an object property in an array state container?? React Hooks useState

I'm React beginner and tried to make a simple Todo app. The app cans add, delete all tasks o delete just one.

The component Todo Form contains an input and two buttons, the first its used to add task, and the last it's for drop all task. So when add a task, the current value of input is pushed to another state called posts. Then the state of posts is shared as a property in other component called "TodoList" who shows a list display of posts(array).

Todo Form Component

import React ,{useState} from 'react'
import TodoList from './TodoList'

function TodoForm() {
    const initialState = {
        id:"",
        description:"",
        status:""
    }

    const [task, setTask] = useState(initialState)
    const [posts, setPosts] = useState([])

    const handleChange = (e) => {
        setTask({
            id:Date.now(),
            description:e.target.value,
            status:false
        })
    }

    const dropArray = (e) => {
        e.preventDefault()
        let confirm = window.confirm("Do you want erase all Tasks?")
        if (confirm){
            setPosts([])
        }
    }
    
    const handleSubmit = (e) =>{
        e.preventDefault()
        if(task.description !== ""){
        setPosts([...posts , task])
        console.log('Post Rendering Array', posts)
    }  else {
        alert("The type box is empty!!")
    }
        setTask({
            id:'',
            description:'',
            status:false
        })
    }

    return (
        <div>
            <h1>What's the plan for Today</h1>
            <form onSubmit={handleSubmit}>
                <input 
                    type="text"
                    value={task.description}
                    onChange={handleChange}
                    placeholder='Type a Message'
                />
                <button>
                    Add Task
                </button>
                <button onClick={dropArray}>
                    Drop Task
                </button>
            </form>
            <TodoList posts={posts} setPosts={setPosts}/>
        </div>
    )
}

export default TodoForm

So, I want when somebody push the Checkbox input, the property "status" change to true/false. When try to change the state using setPosts, I change all array not the object child that I pick.

TodoList Component

import React from 'react'

function TodoList(props) {
    const posts = props.posts

    const deleteTask = (id) => {
        const filteredTask = posts.filter(task => task.id !== id)
        const removeTask = props.setPosts(filteredTask)
    }

    const changeStatus = (post) =>{
        // deleteTask(post.id)
        const status = {
            id: post.id,
            description:post.description,
            status: !post.status
        }

        props.setPosts([status])

        // props.setPosts([status])

        console.log(post)
    }

    return (
        <div>
            <ol>
                {posts.map(post =>{
                return (
                    <li key={post.id}>
                        <textarea readOnly value={post.description}/>
                        <input type="checkbox" onChange={()=>changeStatus(post)} checked={post.status}/>
                        <button onClick={()=>deleteTask(post.id)}>X</button>
                        <button>+</button>
                    </li>
                )
            })}
            </ol>
        </div>
    )
}

export default TodoList

You should find and change the exact item in changeStatus :

  const changeStatus = post => {
    props.setPosts(prev => prev.map(
      item => item.id === post.id 
        ? {...item, status: !item.status}
        : item
    ))
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM