如何在过滤地图列表时更新不可变的键值

How to update key value in immutable while filtering over List of Maps

我有一个不可变列表,如下所示:

 this.state = {
      suggestedUsers: fromJS([
                        {
                          user: {
                            client_user_id: "1234567890",
                            full_name: "marty mcfly",
                            image: "imageURL",
                            role_name: "Associate Graphic Designer",
                            selected: false
                           }
                         },
                         {
                          user: {
                            client_user_id: "0987654321",
                            full_name: "doc",
                            image: "imageURL",
                            role_name: "Software Engineer",
                            selected: false
                           } 
                         }                
                       )]

这用于在 UI 中显示此信息的 div。 当我点击 div 时,我有一个函数被触发,如下所示:

    selectUser(clientUserId){

    // set assessments variable equal to the current team from the state
    let assessments = fromJS(this.state.suggestedUsers)

    let selectAssessor

    // set a variable called selectedUsers equal to the results of filtering over the current suggestedUsers from the state
    let selectedUsers = assessments.filter((obj) => {

        // store immutable retrieval of the client user id in a variable called userId
        let userId = obj.getIn(["user", "client_user_id"])

        // when the user clicks 'Add' user, if the id of the user matches the selected user id
        // the user, represented here by obj, is pushed into the selectedUsers array stored in the state.
        if(userId === clientUserId){
            return obj.setIn(["user", "selected"], true)
        }

        // If the user id is not equal to the selected user, that team member is kept in the
        // current team array represented by the state. 
        return userId !== clientUserId
    })

        // update the state with the current representation of the state determined by the user
        // selected team members for assessment requests
        this.setState({
          suggestedUsers: selectedUsers
        })

    }

我的核心问题是:

我想在调用此函数时将用户对象中 'selected' 键的值更新为 false。

我知道我不能改变我直接过滤的列表,但我已经尝试了多种不同的方法来更新选定的值(即使用 updateIn 和 setIn)。我知道我需要将调用 setIn 的结果设置为一个变量,并将 return 设置为我正在过滤的列表,但我无法在现有列表中获取要更新的值。任何帮助是极大的赞赏。谢谢!

我已经证实,当我手动更改值时,它可以正常工作。如何通过更新此列表将其更改为不可变的。

=========================================== ============================

感谢社区的反馈。过滤和映射确实被证明是矫枉过正的。使用 immutability-helper,我可以在单击的索引处更新特定用户的选定值。一个没有提到的警告是使用合并将更新的数据合并到以前的数据中。在使用不变性助手更新后,我将更新后的值推送到一个数组中,然后将其制成一个列表,并将其合并到我的原始数据中。代码如下:

let users = this.state.teamAssessments

let selectedArray = []

users.map((obj, index) => {

    let objId = obj.getIn(["user", "client_user_id"])

    if(objId === clientUserId){

        const selectedUser = update(this.state.teamAssessments.toJS(), {

            [index]: { 

                user : {

                    selected: {

                        $set: true

                    }

                }

            }

        })

        selectedArray.push(selectedUser)

    }

})

let updatedArray = fromJS(selectedArray).get(0)

let mergedData = users.merge(updatedArray)

this.setState({

    teamAssessments: mergedData

}) 

你需要immutability-helper。基本上,无需克隆整个对象,只需修改对象的一小部分并在完成后重新设置状态。

import update from 'immutability-helper';

const newData = update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});

this.setState({varName: newData});

换句话说,我会在枚举数组时放弃 fromJS 和修改数组。首先,枚举数组并创建更新。然后,单独应用更新。另外,对我来说 "selected" var 似乎是多余的,因为你知道它们是否被选中,因为过滤后的数组名称是 "selectedUsers."

如果我对你的问题的理解正确,我的建议如下:

selectUser(clientUserId) {
    let suggestedUsers = this.state.suggestedUsers.map(
        userBlock =>
            userBlock.setIn(
                ['user', 'selected'],
                userBlock.getIn(['user', 'client_user_id']) === clientUserId
            )
     );
     this.setState({
         suggestedUsers,
     });
}

确认 - 您只是想修改 state.suggestedUsers 以使 selected 对所选用户为真,对其他人为假?听起来非常适合 Immutable 的 map 函数(而不是 filter,它只会 return 列表中的元素,您的谓词函数 return 是真实的)。

顺便说一句,您传递给 fromJS 的对象有一个错误——您需要在第一个 assessor_assessment 块之后添加一个额外的 },