Javascript 简化切换和设置状态更新项';s属性

Javascript 简化切换和设置状态更新项';s属性,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,切换项和更改属性的值非常常见,但我仍然编写这种代码 handleToggle = (id) => { const updatedTodos = this.state.todos.map(todo => { if(todo.id === id){ todo.completed = !todo.completed } return todo })

切换项和更改属性的值非常常见,但我仍然编写这种代码

handleToggle = (id) => {
        const updatedTodos = this.state.todos.map(todo => {
            if(todo.id === id){ 
                todo.completed = !todo.completed 
            }

            return todo
        })

        this.setState({
            todos: updatedTodos
        })
    }

没有什么问题,但我发现这是我必须写大量代码的部分。与push不同,我可以使用spread运算符,也可以使用remove运算符,我可以简单地使用一个线性过滤器方法。您知道如何缩短上述代码吗?

您可以使用
对象。分配
以缩短某些内容:

handleToggle = (id) => {
    const updatedTodos = this.state.todos.map(todo =>
        Object.assign({}, todo, (todo.id === id) ? { completed: !todo.completed } : {}))

    this.setState({
        todos: updatedTodos
    })
}
编辑:使用短路求值而不是三值运算符,可以将其缩短一点:

handleToggle = (id) => {
    const updatedTodos = this.state.todos.map(todo =>
        Object.assign({}, todo, todo.id === id && { completed: !todo.completed }))

    this.setState({
        todos: updatedTodos
    })
}

不是最短的,但可读性更高:

import update from 'immutability-helper';

handleToggle = (index) => {

    var oldTodos = this.state.todos
    var todo = oldTodos[index]

    var todos = update(oldTodos, {
        [index]: {
            completed: {
                $set: !todo.completed
            }
        }
    })

    this.setState({ todos })
}

我将item的
索引作为参数传递,而不是
id

根据我的假设,您只需要根据id在状态数组中切换一个值

您可以使用
findIndex
ES6函数获取索引,然后像这样切换其值

handleToggle = (id) => {
    var todos = [...this.state.todos];
    var idx = todos.findIndex(obj => obj.id === id);
    todos[idx].completed = !todos[idx].completed;

    this.setState({
        todos
    })
}

第一个参数,
{}
是必需的吗?它可以是
对象。赋值({},todo,todo.id==id&&&{completed:!todo.completed}))
?第一个参数是针对目标对象的(检查此处:),它确实是一个必需的参数。如果我们将todo作为第一个参数传递,它将被改变,在“避免突变”等方面可能不需要什么。是的,它可以!我可以根据您的建议编辑我的答案:p@MadelineRies您的建议效果很好,因为如果我们将
false
(对于其他todo项)作为
对象的源参数传递。assign
,它将被忽略!例如:
Object.assign({},{a:1},false)
返回
{a:1}