JavaScript |展开运算符更新嵌套值

JavaScript | Spread operator update nested value

我正在尝试使用扩展运算符更新对象的嵌套值。这是我第一次使用它,我相信我已经非常接近实现我的最终目标,但我似乎无法弄清楚接下来我真正需要做什么。

我有一个结构如下的数组:

[
    {
        name: "Category 1",
        posts: [
            {
                id: 1,
                published: false,
                category: "Category 1"
            },
            {
                id: 2,
                published: true,
                category: "Category 1"
            }
        ]
    },
    {
        name: "Category 2",
        posts: [
            {
                id: 3,
                published: true,
                category: "Category 2"
            },
            {
                id: 4,
                published: true,
                category: "Category 2"
            }
        ]
    }
]

在单击按钮时,我试图更新发布的值,并且因为我使用的是 React,所以我需要设置状态。所以有人建议我使用传播运算符进行更新。

onPostClick(post) {
    post.pubished = !post.published;
    this.setState({...this.state.posts[post.category], post})
}

如果我注销 {...this.state.posts[post.category], post} 的结果,我可以看到已发布的内容被添加到形成以下形式的父级:

{
    name: "Category 1",
    published: false,
    posts: [
        ...
    ]
}

显然这不是预期的结果,我希望它更新 posts 对象中的实际对象。

我曾尝试做类似 this.setState({...this.state.posts[post.category].posts, post}) 的事情,但我收到一条消息说它未定义。

您无法使用 this.state.posts[post.category] 访问您的数据。 posts数组对象中的数据。

您可以创建一个过滤器以在数组中查找您的类别对象并更改其帖子值。

onPostClick(post) {
    //CLONE YOUR DATA
    var postArray = this.state.posts;

    //FIND YOUR CATEGORY OBJECT IN ARRAY
    var categoryIndex = postArray.findIndex(function(obj){
        return obj.name === post.category;
    });

    //FIND YOUR POST AND CHANGE PUBLISHED VALUE
    postArray[categoryIndex].posts.forEach(function(item){
       if (item.id === post.id) {
           item.published = !item.published;
       } 
    });
    //SET TO STATE TO RERENDER
    this.setState({ posts: postArray});
}

如果您的州名是真实的,这应该有效。

补充一下,我们知道有很多方法可以成功,也许你也想尝试这种方法..

onPostClick = post => {
    let published = this.state.data.map((item, i) => {
      item.posts.map((item_post, i) => {
        if (item_post.category === post.category) {
          item_post.published = !post.published;
        }
      });
    });
    this.setState({ ...this.state.data, published });
 };