V
V
vovashaplin2020-08-27 15:53:48
React
vovashaplin, 2020-08-27 15:53:48

Why is it impossible to remake a class into a functional component?

What is commented out worked well, but what is not commented out does not work. The error lies in UseEffect in the line WebSocketInstance.addCallbacks(setMessagesHandler, addMessageHandler); (It used to be .bind(this))

// import React from 'react';
// import { connect } from 'react-redux';
// import { BrowserRouter as Router } from 'react-router-dom';
// import * as authActions from './store/actions/auth';
// import * as navActions from './store/actions/nav';
// import * as messagesActions from './store/actions/messages';
// import BaseRouter from './routes';
// import WebSocketInstance from './websocket';
// import { Alert } from './components/Alert';
// import Layout from './components/Layout/Layout';

// class App extends React.Component {

//   componentDidMount() {
//     this.props.onTryAutoSignup();
//     WebSocketInstance.addCallbacks(this.props.setMessages.bind(this), this.props.addMessage.bind(this));
//   }

//   constructor(props) {
//     super(props);
//   }

//   render() {
//     return (
//       <Router>
//         <Layout>
//           <Alert />
//           <BaseRouter isAuth={!!localStorage.getItem('token')} />
//         </Layout>
//       </Router>
//     );
//   };
// }

// const mapStateToProps = state => {
//   return {
//     showAddChatPopup: state.nav.showAddChatPopup,
//     isAuth: !!state.auth.token
//   }
// }

// const mapDispatchToProps = dispatch => {
//   return {
//     onTryAutoSignup: () => dispatch(authActions.authCheckState()),
//     closeAddChatPopup: () => dispatch(navActions.closeAddChatPopup()),
//     addMessage: message => dispatch(messagesActions.addMessage(message)),
//     setMessages: messages => dispatch(messagesActions.setMessages(messages))
//   }
// }

// export default connect(mapStateToProps, mapDispatchToProps)(App);


import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { setMessages, addMessage } from './store/actions/messages';
import { authCheckState } from './store/actions/auth';
import WebSocketInstance from './websocket';
import { BrowserRouter as Router } from 'react-router-dom';
import BaseRouter from './routes';
import { Alert } from './components/Alert';
import Layout from './components/Layout/Layout';

const App = () => {

  const isAuth = useSelector(state => !!state.auth.token);

  const dispatch = useDispatch();

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

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

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

  return (
    <Router>
      <Layout>
        <Alert />
        <BaseRouter isAuth={!!localStorage.getItem('token')} />
      </Layout>
    </Router>
  );
}

export default App;

I also give the WebSocketInstance component in order to see the full picture of what is happening.
import Chat from "./containers/Chat";

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;

I wanted to convert WebSocketInstance into a functional component, but for me it turned out to be an impossible task. Namely, what is above the connect() method

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question