Переключение между состояниями в реакции - PullRequest
0 голосов
/ 29 апреля 2020

Итак, я создаю приложение чата для школьного проекта с 3 другими учениками, и мы застряли, пытаясь заставить каналы щелкнуть, а затем показать сообщения чата для других клиентов, подключенных к этому каналу.

React, Next js, Socket.io и Express используются, но я не думаю, что это будет иметь какое-либо отношение к бэкэнду, потому что у нас есть отправка сообщений чата и все такое хорошее вещи ..

Проблема, я думаю, связана с редуктором, ну, я знаю, потому что он установлен на action.payload .. Но, редуктор и Onclick, которые я знаю, точно не верны, я не думаю, ..

РЕДАКТИРОВАТЬ: Я дам немного больше контекста о том, что происходит, и в чем проблема ..

У нас есть каналы, перечисленные в боковой панели, по щелчку канала и в консоль мы получаем что-то вроде этого

{selectedChannel: "general", allChats: {…}}
allChats: {general: Array(4), channel2: Array(1)}
selectedChannel: "general"
__proto__: Object

Теперь скажем, что мы щелкаем по второму каналу, который правильно назначен как канал 2, мы получаем то же самое, но мы хотим, чтобы канал изменил сообщения только на отправить на этот канал.

Store. js -

        import React from "react";
    import io from "socket.io-client";
    export const CTX = React.createContext();

    const initState = {
      selectedChannel: 'general',
      allChats: {
        general: [
          { from: 'user1', msg: 'hello' },
          { from: 'user2', msg: 'u stink' },
          { from: 'user3', msg: 'some other words' }
        ],
        channel2: [
          { from: 'user1', msg: 'hello' }
        ]
      }
    }
    const reducer = (state, action) => {
      const { from, msg } = action.payload;
      console.log(state);
      switch (action.type) {
        case 'SET_SELECTED_CHANNEL':
          return {
            ...state,
            selectedChannel: actop.payload,
          }
        case 'RECEIVE_MESSAGE':
          return {
            ...state,
            allChats: {
              ...state.allChats,
              [state.selectedChannel]: [
                ...state.allChats[state.selectedChannel],
                { from, msg }
              ]
            }
          }
        default:
          return state
      }
    }
    let socket;

    const sendChatAction = (value) => {
      socket.emit("chat message", value);
    };

    export const Store = (props) => {
      const [state, dispatch] = React.useReducer(reducer, initState)

      if (!socket) {
        socket = io(':3001')
        socket.on('chat message', function (msg) {
          dispatch({ type: 'RECEIVE_MESSAGE', payload: msg });
        })
      }


      const user = 'RandomUser'


      return (
        <CTX.Provider value={{ state, sendChatAction, user }}>
          {props.children}
        </CTX.Provider>
      )
    }


Here is our Sidebar component where the channels are 

Sidebar.jsx - 

mport React from "react";
import SingleChannel from "./SingleChannel";
import styled from "styled-components";
import { Store, CTX } from './Store';
const Sidebar = () => {
  const { state, sendChatAction } = React.useContext(CTX);
  console.log(state);
  const channel = Object.keys(state.allChats);
  const changeActiveChannel = (eaChannel) => {
    sendChatAction({ type: "SET_SELECTED_CHANNEL", payload: eaChannel })
  }
  return (
    <SideNav>
      {
        channel.map((eaChannel, i) => (
          <SingleChannelWrapper key={i} onClick={() => { changeActiveChannel(eaChannel) }}>
            <SingleChannel eachChannel={eaChannel} key={i} />
          </SingleChannelWrapper>
        ))
      }
    </SideNav>
  );
}

SingleChannel.jsx -

const SingleChannel = (props) => {
  const { state, sendChatAction, } = React.useContext(CTX);
  // console.log(state);
  // console.log(props);
  return (
    <UserWapper>
      <ImageWrapper>
        <UserImage src="/images/user.png" atl="user image" className="channelImage" />
      </ImageWrapper>
      <InfoWrapper>
        <UserName>{props.eachChannel}</UserName>
      </InfoWrapper>
    </UserWapper>
  );

}
...