Updating state with React and Websockets
This seems reasonable. The most important part is that you do not mutate the react state in-place. By doing let currentUser = [...users]; you copy the state and instead mutate the copy, then assign it as the updated state.

An alternative would be to use .map and .filter to make your changes. I see this pattern more often than the state copy approach.

Example:

ws.on("feed", response =&gt; {
  const { new_val: next, type } = response; // Use destructuring and inline renaming.

  setUsers(users =&gt; {
    switch (type) {
      case "add":
        return [...users, next];

      case "change":
        return users.map(u =&gt; {
          // Only change the user specified in the message
          if (u.id === next.id) return {...u, name: next.name } 
          return u;
          // or return users.map(u =&gt; u.id !== next.id ? u : ({...u, name: next.name})) if you prefer one-liners
        })

      case "remove":
        return users.filter(u =&gt; u.id !== next.id);

      default:
        return users;
    }
  });
});