2017-04-12 2 views
2

Donc, fondamentalement, j'ai eu cette prise, qui fonctionne correctement en m'envoyant un message «nouvelle commande». J'utilise redux, et je veux envoyer une action, qu'un réducteur l'obtiendrait et mon magasin serait mis à jour. mais ce code ne fait rien!Dispatch action sur le rappel de socket.on()

socket.on('new order', (order) => {  
    return (dispatch) => { 
     dispatch(socketNewOrder(order)); 
    } 
}); 

Et voici mon action, qui est situé dans le même fichier:

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

J'ai aussi essayé d'appeler mon action comme ceci:

socket.on('new order', (order) => {  
    socketNewOrder(order));   
}); 

Il a appelé l'action bien , mais l'action n'a pas été "entendue" par mon réducteur! :(

J'ai entendu parler à l'aide intergiciels, mais je ne peux pas comprendre comment le faire.

Quelqu'un pourrait-il me expliquer comment utiliser intergiciels pour les actions dispatching que je reçois des messages de socket, et pourquoi mon le code ne fonctionne pas? Merci et désolé pour les débutants questio

+0

Vous renvoyez une fonction qui n'est jamais appelée depuis votre gestionnaire d'événements de socket. Qu'attendez-vous de faire? Et, parce que la fonction n'est jamais appelée, votre fonction 'dispatch()' n'est jamais appelée. Voulez-vous simplement faire ceci: 'socket.on ('new order', (order) => { dispatch (socketNewOrder (commande)); });'? – jfriend00

+0

si je fais cela, il est dit que la répartition n'est pas une fonction! –

+0

Qu'est-ce que 'dispatch()' alors? – jfriend00

Répondre

2

Le point est que vous devez avoir accès à dispatch dans votre écouteur d'événement de prise. L'utilisation d'un middleware pour créer des actions à partir de sources d'événements externes est un motif valable.

const socketMiddleware = (store) => { 
    // We have access to store, add socket listeners 
    socket.on('new order', (order) => {  
    store.dispatch(socketNewOrder(order)); 
    }); 

    // Actual middleware implementation just passes all 
    // actions through without touching them 
    return (next) => (action) => { 
    next(action); 
    } 
} 
+0

Cette implémentation de middleware hardcode les noms des événements. Aussi où est l'instance de socket étant référencé. Serait-il préférable de passer dans l'instance socket comme argument à l'appel middleware avant l'argument du magasin? – therewillbecode

2

Ce code devrait fonctionner pour vous:

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 

Explication

Votre fonction de gestionnaire d'événements ont été correctement cassé en une série de fonctions. Cependant, ces fonctions étaient dans le mauvais ordre.

socket.on('new order', (order) => {  
    return (dispatch) => { 
     dispatch(socketNewOrder(order)); 
    } 
}); 

Ceci est l'ordre des fonctions de la série qui composent votre fonction eventHandler:

socket.on('new order', (dispatch) => {  
    return (order) => { 
     dispatch(socketNewOrder(order)); 
    } 
}); 

Liaison d'une fonction de gestionnaire à une prise de façon normale ressemblerait. Par conséquent, la fonction gestionnaire ne sera appelée que lorsque l'événement est déclenché.

Cela ne fonctionnera pas pour nous si nous devons passer l'envoi à handlerFunc lorsqu'il est lié avant que handlerFunc soit appelé lorsque l'événement est déclenché.

Cependant, nous pouvons résoudre ce problème en utilisant une technique de programmation fonctionnelle appelée qui permet de diviser la fonction de gestionnaire d'événements en une série de fonctions qui peuvent être appelées à un moment ultérieur.

Currying est quand vous cassez une fonction qui prend plusieurs arguments dans une série de fonctions qui prennent part des arguments.

Il existe deux points importants dans le temps pour les événements de socket.

  1. La fonction de gestionnaire est lié à l'instance de prise

  2. La fonction de gestionnaire est appelé

Nous avons accès à la méthode d'expédition du magasin Redux à timepoint un mais pas à timepoint deux . Currying nous permet de «stocker» la méthode d'expédition pour timepoint deux. Donc, ce que nous pouvons faire est d'appeler une fonction avec dispatch qui retourne notre handlerFunction.

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

function passDispatch(dispatch){ 
    return handlerFunc 
}; 

socket.on('event', passDispatch(dispatch)); 

Donc même si cela peut sembler étrange, cela donne exactement la même chose que le premier exemple. En cours d'exécution, bien que le gestionnaire d'événements sera appelé à un moment ultérieur, nous serons toujours en mesure d'envoyer des actions lorsque nous aurons accès à la variable dispatch.

Nous pourrions utiliser le middleware pour alléger la répétition de l'exécution de nos fonctions de gestionnaire chaque fois qu'ils sont liés.