【问题标题】:override existing objects when push into an array - replace or add推入数组时覆盖现有对象 - 替换或添加
【发布时间】:2020-06-20 05:52:05
【问题描述】:

假设我们尝试连接 web socket。 web socket服务器发送一些数据来获取代表在线或离线的客户端状态。我试图将这些数据存储到 redux 中(工作正常),但我需要通过覆盖现有对象来立即更改这些状态​​。我需要一些功能来覆盖我的 redux 商店。到目前为止,我使用下面的 sn-p。

但是:

此代码将对象推送到我的 redux 商店而不是覆盖

  const [status, set_status] = useState([]);

  useEffect(() => {
    const socket = io(ws_api, {
      query: `token=${localStorage.getItem("token")}`,
    });

    socket.on("message", (data) => {

      status.map((item) => {
        if (item.application === data.application) {
          item["status"] = data.status;
        } else {
          set_status((status) => [...status, data]);
        }
      });

    });
  }, []);

  useEffect(() => {
    get_client_status(status); // redux action
  }, [status]);

来自消息套接字的数据结构

{
  application: "5ede25f4d3fde1c8a70f0a38"
  client: "5ede25f4d3fde1c8a70f0a36"
  status: "offline"
}

【问题讨论】:

  • 您要在onMessage 回调中更新或添加消息吗? IE。查看并修复共享的代码?
  • 您是否考虑过将状态改为使用 Object 或 Map 而不是 Array?

标签: javascript reactjs react-hooks react-lifecycle


【解决方案1】:

首先搜索任何现有数据元素的当前状态,如果找到则更新它,否则添加到数组中。

使用array::findIndex

const messageHandler = data => {
  const dataIndex = status.findIndex(
    item => item.application === data.application
  );

  if (dataIndex !== -1) {
    set_status(status =>
      status.map(item => {
        return item.application === data.application
          ? { ...item, status: data.status }
          : item;
      })
    );
  } else {
    set_status(status => [...status, data]);
  }
});

使用array::find

const messageHandler = data => {
  const found = status.find(item => item.application === data.application);

  if (found) {
    set_status(status =>
      status.map(item => {
        return item.application === data.application
          ? { ...item, status: data.status }
          : item;
      })
    );
  } else {
    set_status(status => [...status, data]);
  }
});

编辑:在效果之外定义这个回调

useEffect(() => {
  socket.on("message", messageHandler);
}, []);

【讨论】:

  • 因为这段代码在使用效果(componentDidMount)内,每次消息来回返回-1我不知道它会怎么去固定
  • 啊,是的,onMessage 回调包含在范围内,以及挂载时的状态值。尝试在效果之外定义数据处理程序回调。我会更新答案。
  • 效果外的数据处理程序回调只是将对象推入数组而不是覆盖:(
  • @MA2WEB 你知道吗,重新阅读你的问题,如果你发送要存储在那里的消息将它们保存在本地组件中,我看到你保持重复状态状态。你是说你的 redux 存储中的数据没有覆盖吗?我认为解决方案是onMessage 将消息发送到reducer 以更新您的状态。逻辑基本相同,您将更新您的单一事实来源。
猜你喜欢
  • 2017-06-24
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多