简体   繁体   中英

Add key/value pair to existing array of objects

I have an array of objects that is saved into a userList useState which is composed of:

[{
    firstName: "blah" 
    lastName: "blah2"
 }

 {
    firstName: "test"
    lastName: "test2"
}]

I have a useEffect that calls a function and returns a value. I want to store a new key and value to each user in userList.

useEffect(() => {

        userList.forEach((user, index) =>
            returnNewValueForNewKeyFunction(user, index).then(newValue => {

                userList[index]['newKey'] = newValue
                //this console.log shows new field and value
                console.log(userList)
                //this console.log ALSO shows new field and value
                console.log(JSON.stringify(contactList[index]))
            })
        )
    }
}, [])

This is fine if I'm operating out of console.log, but unfortunately I need to render the data onto the page.. in my render I have:

return (
    <TableBody>
        {userList
            .map((user, index) => (
                 <TableRow>
                     <TableCell>
                         {user.newKey}
                     </TableCell>
)

user.newKey is showing as blank and it seems like the user wasn't updated at all. How can I make it so the value is actually updated and can be read from when rendering?

You shouldnt mutate your list, you should use useState to store your list, so something like this:

const [ state, setState] = useState(userList);

Then when you want to update, do something like this:

const listCopy = [...state];
//Logic to update your list here
listCopy[index][otherindex] = Value;
setState(listCopy)

Hope this helps

You are modifying your userList but not calling your set function on which means React won't know to re-render with the updated state.

Instead of mutating the current state, you should create a new array and then call the set function returned by useState with the updated array after making your changes.

It also looks like your returnNewValueForNewKeyFunction is a promise / async which means each of your item changes are happening async . You'll need to make these synchronous / wait for them all before updating your state to make your state change a single update for the UI.

Eg, putting these both together - if you are doing:

const [userList, setUserList] = useState();

You could do:

useEffect(() => {
    // Since can't use an async func directly with useEffect -
    // define an async func to handle your updates and call it within the useEffect func
    const updateUsers = async () => {
        // Create a new array for your updated state
        const updatedUserList = [];

        // Loop over your values inline so your can await results to make them sync
        for (let index = 0; index < userList.length; index ++) {
            const user = userList[index];
            const newVal = await returnNewValueForNewKeyFunction(user, index);

            // Create a shallow copy of the original value and add the newValue
            updatedUserList[index] = { ...user, newKey: newValue };
            // ... Any other logic you need
        }

        // Call set with the updated value so React knows to re-render
        setUserList(updatedUserList);
    };

    // Trigger your async update
    updateUsers();
}, [])

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