Задать вопрос
@vovashaplin

Почему не получается переделать class в функциональный компонент?

То, что закомментировано хорошо работало, но то что не закомментировано не работает. Ошибка кроется в UseEffect'е в строчке WebSocketInstance.addCallbacks(setMessagesHandler, addMessageHandler); (Раньше там было .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;

Также привожу компонент WebSocketInstance, дабы видеть полную картину происходящего.
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;

Я хотел переделать WebSocketInstance в функциональный компонент, но для меня это оказалось непосильной задачей. А именно то, что выше метода connect()
  • Вопрос задан
  • 53 просмотра
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы