动态获取 Redux State:确保 WebSocket 连接使用最新的应用状态

问题描述:
假设我们在一个 React 组件中需要创建一个 WebSocket 连接,并在连接时执行一些操作(比如更新状态、获取数据等)。我们通过传递 store.getState() 方法来获取 Redux store 的状态。
然而,若直接将 store.getState() 作为参数传递给 Connect 类,那么它只能获取初始的 state,而不是随着组件的更新而变化的最新 state。因此,问题在于如何确保 Connect 类内部能始终使用最新的 state。

解决方案:
我们可以通过传递一个返回 state 的函数来解决这个问题,而不是直接传递 store.getState()。这样,在 Connect 类内部使用这个函数时,能够实时获取到最新的 state,而不是初始的静态状态。

修改代码

在 useEffect 中动态传递 getState 函数
import { useStore } from 'react-redux';
const store = useStore();

useEffect(() => {
  // 传递动态的获取 state 的方法,而不是直接传递 store.getState
  const ws = new Connect(dispatch, () => store.getState());
  ws.connect();
  setActive('/message');

  return () => ws.disconnect();
}, [dispatch, store]);  // 将 store 作为依赖项,确保 getState 是最新的

在这个修改后的 useEffect 中,我们传递了一个动态的函数 () => store.getState()。这个函数每次都会返回当前的 state,从而确保 Connect 类中的 getState 始终能够获取到最新的状态。

在 Connect 类中使用动态获取 state 的方法

class Connect {
    constructor(dispatch, getState) {
        this.dispatch = dispatch;
        this.getState = getState; // 动态获取 state

        this.conn = new WsSocket(getWebSocketUrl, {
            onError: (evt) => {
                console.log('WebSocket connection failed:', evt);
            },
            onOpen: () => {
                console.log("WebSocket connected");
                dispatch(updateSocketStatus(true));
                dispatch(fetchTalks());
            },
            onClose: () => {
                dispatch(updateSocketStatus(false));
            }
        });

        this.bindEvents();
    }

    connect = () => {
        this.conn.connection();
    }

    disconnect = () => {
        this.conn.onClose();
    }

    isConnect = () => {
        return this.conn.connect?.readyState === 1;
    }

    emit = (event, data) => {
        this.conn.emit(event, data);
    }

    bindEvents = () => {
        // Basic events
        this.conn.on('ping', () => this.emit('pong', ''));
        this.conn.on('pong', () => { });

        // Error handling
        this.conn.on('event_error', (data) => {
            alert(JSON.stringify(data));
        });

        // Message events
        this.conn.on('im.message', (data) => {
            const currentState = this.getState();  // 获取最新的 state
            if (this.dispatch) {
                new EventTalk(this.dispatch, () => currentState, data);
            }
        });
    }
}

在 Connect 类的构造函数中,我们保存了 getState 函数,而不是直接保存一个静态的 store.getState()。这样,每次在 WebSocket 事件触发时,我们都能通过调用 this.getState() 获取最新的 Redux store 状态。

如何使 EventTalk 获取到最新的 state

class EventTalk {
    constructor(dispatch, getState, data) {
        this.dispatch = dispatch;
        this.getState = getState;  // 获取最新的 state
        this.data = data;
    }

    // 处理消息
    processMessage() {
        const currentState = this.getState();  // 获取最新的 state
        // 在这里,你可以根据最新的 state 和接收到的消息进行处理
        console.log("Current state:", currentState);
        console.log("Received message:", this.data);
    }
}

在 EventTalk 中,通过 getState 方法获取当前的最新 state,从而确保我们每次处理消息时都能得到最新的应用状态。

为什么要使用 () => store.getState() 而不是 store.getState()?

  • store.getState() 是静态的:如果我们直接传递 store.getState(),它将引用组件渲染时的 store 状态快照,而不会随时间更新。
  • () => store.getState() 是动态的:通过传递一个返回 state 的函数,我们可以确保每次获取最新的状态,而不是使用首次渲染时的状态。

总结

通过这种方式,我们能够确保 Connect 类和 EventTalk 类始终能够获取到最新的 Redux state。这种动态获取 state 的方法避免了将静态的 getState 传递给 Connect,使得组件在更新时能够始终使用到最准确的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值