pusher.bind 方法中过时的反应状态

问题描述 投票:0回答:3

我使用

pusher-js
从后端接收数据。


我在

useEffect
中配置它,如下所示:

  useEffect(() => {
    const pusher = new Pusher('my_app_id', {
      cluster: 'us3',
    });

    const channel = pusher.subscribe('messages');

    channel.bind('send-message', (data) => {

    });
  }, []);

.bind
方法的回调中,我想访问react状态。问题是,如果更新了,这个回调仍然是旧版本。

channel.bind('send-message', (data) => {
    // here is my outdated state
});

如何在该回调中访问新的、更新的状态? 预先感谢

reactjs state pusher pusher-js
3个回答
3
投票

在 useEffect 的依赖数组中使用另一个具有更新状态的 useEffect,一旦状态更新,useEffect 就会更新。被触发并在其中您可以访问更新的状态。


2
投票

我被同一个问题困扰了很长一段时间。我最终解决这个问题的方法是存储通道并在每次状态(我想在绑定回调中访问)发生变化时重新绑定事件。这是一个代码片段,可以帮助您更好地理解。

非常重要 - 在重新绑定事件之前,不要忘记从通道中解除事件绑定。由于重新绑定而不取消绑定先前的绑定只会为该事件创建额外的侦听器,并且当事件发生时所有侦听器都会触发,这将是一团糟。经历了一番艰难才学会的:")

不知道这是否是最好的方法,但对我有用。

const [pusherChannel, setPusherChannel] = useState(null);
const [data, setData] = useState(null);

// TRIGGERED ON MOUNT
useEffect(() => {
  const pusher = new Pusher(APP_KEY, {
    cluster: APP_CLUSTER
  });
  const channel = pusher.subscribe(CHANNEL_NAME);
  setPusherChannel(channel);
  // PREVIOUSLY
  // channel.bind(EVENT_NAME, (pusherData) => {
  //   ...
  //   Accessing "data" here would give the state used
  //   during binding the event
  //});
}, []);

// TRIGGERED ON CHANGE IN "data"
useEffect(() => {
  console.log("Updated data : ", data);
  if(pusherChannel && pusherChannel.bind){
    console.log("Unbinding Event");
    pusherChannel.unbind(EVENT_NAME);
    console.log("Rebinding Event");
    pusherChannel.bind(EVENT_NAME, (pusherData) => {
      // USE UPDATED "data" here
    }
  }
}, [pusherChannel, data]);

参考-


0
投票

如果您想将消息推送到当前消息列表,请不要使用 useState 中的 getter。使用设置器中的函数。第一个参数是您的实际消息列表。 例如:

const [messageList, setMessageList] = useState([]);

useEffect(() => {
    const pusher = new Pusher('my_app_id', {
      cluster: 'us3',
    });

    const channel = pusher.subscribe('messages');

    channel.bind('send-message', (data) => {
        setMessageList([data.message, ...messageList]); // ❌ Wrong way
        setMessageList(actualMessages => [data.message, ...actualMessages]); // ✅ Good way
    });
  }, []);
© www.soinside.com 2019 - 2024. All rights reserved.