对 socket.on() 回调的调度操作

Ama*_*ira 4 sockets action dispatch socket.io redux

所以基本上我得到了这个套接字,它工作正常,向我发送“新订单”消息。

我正在使用 redux,我想分派一个动作,而不是减速器会得到它并且我的商店会被更新。但这段代码没有做任何事情!

socket.on('new order', (order) => {    
    return (dispatch) => {
      dispatch(socketNewOrder(order));
    }
});
Run Code Online (Sandbox Code Playgroud)

这是我的操作,它位于同一个文件中:

export const socketNewOrder = (order) => {
  return {
    type: 'SOCKET_NEW_ORDER',
    payload: order
  }
}
Run Code Online (Sandbox Code Playgroud)

我也试着这样称呼我的行动:

socket.on('new order', (order) => {    
    socketNewOrder(order));        
});
Run Code Online (Sandbox Code Playgroud)

它确实调用了动作,但我的减速器没有“听到”动作!:(

我听说了一些关于使用中间件的消息,但我就是不知道如何去做。

谁能解释我如何在接收套接字消息时使用中间件来调度操作,以及为什么我的代码不起作用?感谢和抱歉新手问题

the*_*ode 5

此代码应该适合您:

export const socketNewOrder = (order) => {
  return {
    type: 'SOCKET_NEW_ORDER',
    payload: order
  }
}

const handlerFunc = (dispatch) => (order) => {
    dispatch(socketNewOrder(order));
  }
});

socket.on('event', handlerFunc(dispatch));
// make sure the stores dispatch method is within scope
Run Code Online (Sandbox Code Playgroud)

解释

您的事件处理函数被正确分解为一系列函数。然而,这些功能的顺序是错误的。

socket.on('new order', (order) => {    
    return (dispatch) => {
      dispatch(socketNewOrder(order));
    }
});
Run Code Online (Sandbox Code Playgroud)

这是组成 eventHandler 函数的系列函数的正确顺序:

socket.on('new order', (dispatch) => {    
    return (order) => {
      dispatch(socketNewOrder(order));
    }
});
Run Code Online (Sandbox Code Playgroud)

以正常方式将处理程序函数绑定到套接字看起来像。

socket.on('event', handlerFunc)
Run Code Online (Sandbox Code Playgroud)

所以处理函数只会在事件被触发时被调用。

如果在触发事件时调用 handlerFunc 之前绑定时需要将 dispatch 传递给 handlerFunc,这对我们不起作用。

然而,我们可以通过使用称为柯里化的函数式编程技术来解决这个问题,该技术允许我们将事件处理程序函数分解为一系列可以在稍后的时间点逐步调用的函数。

柯里化是将一个接受多个参数的函数分解成一系列接受部分参数的函数。

套接字事件有两个重要的时间点。

  1. 处理函数绑定到套接字实例

  2. 处理函数被调用

我们可以在时间点 1 访问 Redux 商店的 dispatch 方法,但不能在时间点 2 访问。柯里化允许我们“存储”时间点二的调度方法。

所以我们可以做的是调用一个带有 dispatch 的函数,它返回我们的 handlerFunction。

function handlerFunc(order){
  dispatch(socketNewOrder(order));
}

function passDispatch(dispatch){
  return handlerFunc
};

socket.on('event', passDispatch(dispatch));
Run Code Online (Sandbox Code Playgroud)

因此,尽管这看起来很奇怪,但结果与第一个示例完全相同。通过柯里化,虽然事件处理程序将在稍后的时间点被调用,但我们仍然能够调度动作,因为我们可以访问调度变量。

我们可以使用中间件来减少每次绑定处理程序函数时重复柯里化的情况。