Warm tip: This article is reproduced from stackoverflow.com, please click
react-native redux socket.io

Combining socket.io with a redux reducer

发布于 2020-04-08 09:43:12

The stack - React native, socket.io, Node.js

Im developing a chat app. At this point I have a flow like that : User clicks "send message" -> the message is emitted by socket.io to the server -> the socket connection on the server gets the message. Now, from that point what I want is the message to be sent from the server to the redux reducer and then the reducer will return a new state that the frontend component will render.
How do I make the connection between the server side socket and the reducer?

The current server :

    const express = require("express");
    const app = express();
    const port = 3000;
    const server = require("http").createServer(app);
    let io = require("socket.io")(server);

    app.get("/", (req, res) => res.send("Hello World!"));

    io.on("connection", socket => {
      console.log("a user connected");

      socket.on("join", (name, message) => {
      console.log("chat room connected")
      });

    });

    server.listen(port, () => console.log(`listening on port ${port}!`));

The current reducer :

    const initialState = {
      chats: [

      ]
    };
    const chatsReducer = (state = initialState, action) => {
      let sender = action.sender;
      let message = action.message;

      switch (action.type) {
        case SEND_MESSAGE:
          let newMessage = {
            sender: sender,
            message: message
          };

          let newState = { ...state, chats: state.chats.push(newMessage) };
          return state;

        default:
          state;
      }
      return state;
    };

    export default chatsReducer;
Questioner
apollo24
Viewed
34
Ragnar 2020-02-01 01:22

You can emit the new message from the node server like.

let msg = {message: 'Actual Message', sender: 'Name of sender'}
io.on('connection', socket => {
  socket.on('chat message', msg => {
    io.emit('chat message', msg);
  });
}); 

Then in you chat component listen the chat message event.

 componentDidMount() {
    this.socket = io("http://server.address:port");
    this.socket.on("chat message", msg => {
       this.props.onMessageReceivedAction (msg); // import action and will execute on message received event
   });
});

Then add the action :

export const onMessageReceivedAction = (params) => {
  return  {type: MESSAGE_RECEIVED, payload:msg};
};

Add message received reducer case to your reducer

case MESSAGE_RECEIVED:

  let newMessage = {
    sender: payload.sender,
    message: payload.message
  };

  return { ...state, chats: state.chats.push(newMessage) };

This will return the new state and the component props mapped to the above state will get re-rendered.

Hope this will answer your question.