V
V
vovashaplin2020-08-27 23:46:39
React
vovashaplin, 2020-08-27 23:46:39

How to pass a callback to an instance?

This is how it used to work before

componentDidMount() {
    WebSocketInstance.addCallbacks(this.props.setMessages.bind(this), this.props.addMessage.bind(this));
  }
 ... 
 ...
const mapDispatchToProps = dispatch => {
  return {
    addMessage: message => dispatch(messagesActions.addMessage(message)),
    setMessages: messages => dispatch(messagesActions.setMessages(messages))
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(App);

But I decided to remake the class component into a functional one.
const dispatch = useDispatch();

  const setMessagesHandler = () => {
    dispatch(setMessages());
  }

  const addMessageHandler = () => {
    dispatch(addMessage());
  }

  useEffect(() => {
    dispatch(authCheckState());
    WebSocketInstance.addCallbacks(setMessagesHandler, addMessageHandler);
  }, []);

But the fact is that these two functions take 1 input each and I don’t know how to implement it.
Here are the actions
export const addMessage = message => {
  return {
    type: actionTypes.ADD_MESSAGE,
    message: message
  };
};

export const setMessages = messages => {
  return {
    type: actionTypes.SET_MESSAGES,
    messages: messages
  };
};

Here is the reducer
const addMessage = (state, action) => {
  return updateObject(...state, {
    messages: [...state.messages, action.message]
  });
};

const setMessages = (state, action) => {
  return updateObject(state, {
    messages: action.messages.reverse()
  });
};

Here is the WebSocketInstance where the callbacks are added
class WebSocketService {
  static instance = null;
  callbacks = {};

  static getInstance() {
    if (!WebSocketService.instance) {
      WebSocketService.instance = new WebSocketService();
    }
    return WebSocketService.instance;
  }

  constructor() {
    this.socketRef = null;
  }

  connect(chatUrl) {
    const path = `ws://127.0.0.1:8000/ws/chat/${chatUrl}/`;
    this.socketRef = new WebSocket(path);
    this.socketRef.onopen = () => {
      console.log('WebSocket open');
    };
    this.socketRef.onmessage = e => {
      this.socketNewMessage(e.data);
    };
    this.socketRef.onerror = e => {
      console.log(e.message);
    };
    this.socketRef.onclose = () => {
      console.log("WebSocket closed let's reopen");
      // this.connect(chatUrl);
    };
  }

  disconnect() {
    this.socketRef.close();
  }

  socketNewMessage(data) {
    const parsedData = JSON.parse(data);
    const command = parsedData.command;
    if (Object.keys(this.callbacks).length === 0) {
      return;
    }
    if (command === 'messages') {
      this.callbacks[command](parsedData.messages);
    }
    if (command === 'new_message') {
      this.callbacks[command](parsedData.message);
    }
  }

  fetchMessages(username, chatId) {
    this.sendMessage({ 
      command: 'fetch_messages', 
      username: username, 
      chatId: chatId 
    });
  }

  newChatMessage(message) {
    this.sendMessage({ 
      command: 'new_message', 
      from: message.from, 
      message: message.content, 
      chatId: message.chatId 
    }); 
  }

  addCallbacks(messagesCallback, newMessageCallback) {
    this.callbacks['messages'] = messagesCallback;
    this.callbacks['new_message'] = newMessageCallback;
  }

  sendMessage(data) {
    try {
      this.socketRef.send(JSON.stringify({ ...data }));
    }
    catch(err) {
      console.log(err.message);
    }  
  }

  state() {
    return this.socketRef.readyState;
  }

}

const WebSocketInstance = WebSocketService.getInstance();

export default WebSocketInstance;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
Timur Kostenko, 2020-08-29
@vovashaplin

Well, in theory, message and messages should be stored in props, if not, try passing the parameters directly to the function.

const setMessagesHandler = (messages) => {
  dispatch(setMessages(messages));
}

const addMessageHandler = (message) => {
  dispatch(addMessage(message));
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question