在反应状态之间切换

时间:2020-04-29 17:44:55

标签: javascript node.js reactjs next.js

因此,我正在与其他3个学生一起为一个学校项目构建一个聊天应用程序,而我们一直试图让频道单击,然后显示与该频道连接的其他客户端的聊天消息。

正在使用React,Nextjs,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>
  );

}

0 个答案:

没有答案