问题描述:
假设我们在一个 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,使得组件在更新时能够始终使用到最准确的数据。
5037

被折叠的 条评论
为什么被折叠?



