• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    미해결

채널 생성시 개발자도구에서

21.10.12 15:33 작성 조회수 531

0

안녕하세요 채널 생성시  채널생성이 되지 않고 개발자도구 network란에 "존재하지 않는 워크스페이스 입니다" 라고 뜹니다. 타이핑도 모두 동일하고 어느부분이 잘못됬는지 잘 모르겠습니다.

 

답변 11

·

답변을 작성해보세요.

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

그리고 브라우저 주소창은 다음과 같이 나타납니다.

http://localhost:3090/workspace/sleact/channel/일반

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

layout/workspace/index.tsx  전체 코드입니다.

import {
  Channels,
  Header,
  ProfileImg,
  RightMenu,
  Workspaces,
  WorkspaceWrapper,
  WorkspaceName,
  Chats,
  MenuScroll,
  ProfileModal,
  LogOutButton,
  WorkspaceButton,
  AddButton,
  WorkspaceModal
} from '@layouts/Workspace/styles';
import fetcher from '@utils/fetcher';
import axios from 'axios';
import React,{ VFC, useCallback, useState }  from 'react';
import { Redirect, useParams } from 'react-router';
import { Link, Route, Switch } from 'react-router-dom';
import useSWR from 'swr';
import gravatar from 'gravatar';
import loadable from '@loadable/component';
import Menu from '@components/Menu';
import { IChannel, IUser } from '@typings/db';
import { Button, Input, Label } from '@pages/SignUp/styles';
import useInput from '@hooks/useInput';
import Modal from '@components/Modal';
import { toast } from 'react-toastify';
import CreateChannelModal from '@components/CreateChannelModal';
import InviteWorkspaceModal from '@components/InviteWorkspaceModal';
import InviteChannelModal from '@components/InviteChannelModal';

const Channel = loadable(() => import('@pages/Channel'));
const DirectMessage = loadable(() => import('@pages/Channel'));


const Workspace: VFC = () => {
    const [ showUserMenu, setShowUserMenu] = useState(false);
    const [ ShowCreateWorkspaceModal,setShowCreateWorkspaceModal] = useState(false);
    const [ showInviteWorkspaceModal, setShowInviteWorkspaceModal] = useState(false);
    const [ showInviteChannelModal, setShowInviteChannelModal] = useState(false);
    const [ showWorkspaceModal,setShowWorkspaceModal] = useState(false);
    const [ showCreateChannelModal ,setShowCreateChannelModal] = useState(false);
    const [newWorkspace, onChangeNewWorkspace, setNewWorkspace] = useInput('');
    const [newUrl, onChangeNewUrl, setNewUrl] = useInput('');

    const { workspace } = useParams<{workspace: string}>();
    const { data: userData, error, revalidate } = useSWR<IUser | false>(
      'http://localhost:3095/api/users',
      fetcher,
      {
        dedupingInterval: 2000, // 2초
      }
    );
   
    const { data: channelData } = useSWR<IChannel[]>(
      userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null,
       fetcher,
    );

    const onLogout = useCallback(() => {
      axios.post('http://localhost:3095/api/users/logout', null, {
          withCredentials: true,
      })
       .then(() => {
        revalidate();
       })
    }, []);

    const onCloseUserProfile = useCallback((e) => {
      e.stopPropagation();
      setShowUserMenu(false);
    }, []);

    const onClickUserProfile = useCallback(() => { // 토글함수
      console.trace('click');
      setShowUserMenu((prev) => !prev);
    }, []);

    const onClickCreateWorkspace = useCallback(() => {
      setShowCreateWorkspaceModal(true);
    }, []);

    const onCreateWorkspace = useCallback((e) => {
      e.preventDefault();
      if(!newWorkspace || !newWorkspace.trim()) return;
      if(!newUrl || !newUrl.trim()) return;
      if(!newWorkspace) return;
      axios
      .post('http://localhost:3095/api/workspaces', {
        workspace: newWorkspace,
        url: newUrl,
      },   {
        withCredentials: true,
      })
      .then(() => {
        revalidate();
        setShowCreateWorkspaceModal(false);
        setNewWorkspace('');
        setNewUrl('');
      })
      .catch((error) => {
        console.dir(error);
        toast.error(error.response?.data, { position: 'bottom-center'});
      });
    },
      [newWorkspace, newUrl]
    );

    const onCloseModal = useCallback(() => {
      setShowCreateWorkspaceModal(false);
      setShowCreateChannelModal(false);
      setShowInviteWorkspaceModal(false);
      setShowInviteChannelModal(false);
    }, []);

    const toggleWorkspaceModal = useCallback(() => {
      setShowWorkspaceModal((prev) => !prev);
    }, []);

    const onClickAddChannel = useCallback(() => {
      setShowCreateChannelModal(true);
    }, []);

    const onClickInviteWorkspace = useCallback(() => {

    }, []);

    if(!userData) {
      return <Redirect to="/login" />
    }

    return(
        <div>
          <Header>
           <RightMenu>
             <span onClick={onClickUserProfile}>
               <ProfileImg src={gravatar.url(userData.nickname, { s: '28px', d: 'retro'})} alt={userData.nickname} />
               {showUserMenu && (
                <Menu style={{ right: 0, top: 38 }} show={showUserMenu} onCloseModal={onCloseUserProfile}>
                  <ProfileModal>
                    <img src= {gravatar.url(userData.nickname, { s: '36px', d: 'retro'})} alt={userData.nickname} />
                    <div>
                      <span id="profile-name">{userData.nickname}</span>
                      <span id="profile-active">Active</span>
                    </div>
                  </ProfileModal>
                  <LogOutButton onClick={onLogout}>로그아웃</LogOutButton>
                </Menu>
               )}
             </span>
            </RightMenu>  
          </Header>
          <WorkspaceWrapper>
            <Workspaces>
              {userData?.Workspaces.map((ws) => {
              return(
                <Link key={ws.id} to={'/workspace/${123}/channel/일반'}>
                  <WorkspaceButton>{ws.name.slice(0, 1).toUpperCase()}</WorkspaceButton>
                </Link>
              )
            })}
             <AddButton onClick={onClickCreateWorkspace}>+</AddButton>
            </Workspaces>
            <Channels>
              <WorkspaceName onClick={toggleWorkspaceModal}>Sleact</WorkspaceName>
              <MenuScroll>
                <Menu show={showWorkspaceModal} onCloseModal={toggleWorkspaceModal} style={{ top: 95, left: 80}}>
                  <WorkspaceModal>
                    <h2>Sleact</h2>
                    <button onClick ={onClickInviteWorkspace}>워크스페이스에 사용자 초대</button>
                    <button onClick={onClickAddChannel}>채널 만들기</button>
                    <button onClick={onLogout}>로그아웃</button>
                  </WorkspaceModal>
                </Menu>
                {channelData?.map( (v) => (
                 <div>{v.name}</div>
                ))}
              </MenuScroll>
            </Channels>
            <Chats>
              <Switch> {/* workspace 안에서 Switch Route 사용 (중첩 라우팅)  */}
              <Route path="/workspace/:workspace/channel/:channel" component={Channel} />
              <Route path="/workspace/:workspace/dm/:id" component={DirectMessage} />
              </Switch>
            </Chats>
          </WorkspaceWrapper>
          <Modal show={ShowCreateWorkspaceModal} onCloseModal={onCloseModal}>
            <form onSubmit={onCreateWorkspace}>
              <Label id="Workspace-label">
               <span>워크스페이스 이름</span>
               <Input id ="workspace" value={newWorkspace} onChange={onChangeNewWorkspace} />
              </Label>
              <Label id="Workspace-url-label">
               <span>워크스페이스 url</span>
               <Input id ="workspace" value={newUrl} onChange={onChangeNewUrl} />
              </Label>
              <Button type="submit">생성하기</Button>
            </form>
          </Modal>
          <CreateChannelModal
            show={showCreateChannelModal}
            onCloseModal={onCloseModal}
            setShowCreateChannelModal={setShowCreateChannelModal}
          />
          <InviteWorkspaceModal show={showInviteWorkspaceModal} onCloseModal={onCloseModal} setShowInviteWorkspaceModal={setShowInviteWorkspaceModal} />
          <InviteChannelModal show={showInviteChannelModal} onCloseModal={onCloseModal} setShowInviteChannelModal={setShowInviteChannelModal} />
        </div>
    );
};

export default Workspace;
 

 

 

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

그러면 어느 부분을 보여드려야 되나요? 

 

app의 index.tsx 코드는 다음과 같습니다.

import React from 'react';
import loadable from '@loadable/component';
import { Switch, Route, Redirect } from 'react-router-dom';

// 코드 스플리팅
const LogIn = loadable(() => import('@pages/LogIn'));
const SignUp = loadable(() => import('@pages/SignUp'));
const Workspace = loadable(() => import('@layouts/Workspace')) // workspace만 등록

const App = () => {
  return (
    <Switch>
      <Redirect exact path="/" to="/login" />
      <Route path="/login" component={LogIn} />
      <Route path="/signup" component={SignUp} />
      <Route path="/workspace" component={Workspace} />
    </Switch>
  );
};

export default App;

layouts/Workspace.tsx 보여주세요.

그리고 브라우저 주소창도 확인해보세요.

https://github.com/ZeroCho/sleact/blob/master/front/layouts/App/index.tsx#L16

여기가 다르네요.

이 부분이 없어서 useParams의 workspace가 undefined였습니다.

yjym33님의 프로필

yjym33

질문자

2021.10.12

제로초님 번거롭게 해드려서 죄송하지만 해당부분을 수정해도 계속해서 같은 오류가 발생합니다.

yjym33님의 프로필

yjym33

질문자

2021.10.12

Warning: Each child in a list should have a unique "key" prop.

 

Check the render method of `Workspace`. See https://reactjs.org/link/warning-keys for more information.

    at div

    at Workspace (http://localhost:3090/dist/layouts_Workspace_index_tsx.js:797:90)

    at InnerLoadable (http://localhost:3090/dist/app.js:177:34)

    at LoadableWithChunkExtractor

    at Loadable

    at Route (http://localhost:3090/dist/app.js:54800:29)

    at Switch (http://localhost:3090/dist/app.js:55002:29)

    at App

    at Router (http://localhost:3090/dist/app.js:54431:30)

    at BrowserRouter (http://localhost:3090/dist/app.js:54048:35)

계속 주소에 undefined가 있는 것인가요? useParams에서 나온 workspace를 console.log 해보세요. 그리고 workspace를 사용하는 모든 useCallback에 [workspace]가 되어있는지도요.

yjym33님의 프로필

yjym33

질문자

2021.10.12

app.js:1667 GET http://localhost3095/api/workspaces/sleact/channels net::ERR_NAME_NOT_RESOLVED

localhost3095 오타입니다. localhost:3095입니다.

yjym33님의 프로필

yjym33

질문자

2021.10.12

아.. localhost3095 오류는 제로초님이 말씀해주셔서 수정했습니다 ㅠㅠ 감사합니다 

yjym33님의 프로필

yjym33

질문자

2021.10.12

react_devtools_backend.js:2526 Warning: Each child in a list should have a unique "key" prop.

 

Check the render method of `Workspace`. See https://reactjs.org/link/warning-keys for more information.

    at div

    at Workspace (http://localhost:3090/dist/layouts_Workspace_index_tsx.js:797:90)

    at InnerLoadable (http://localhost:3090/dist/app.js:177:34)

    at LoadableWithChunkExtractor

    at Loadable

    at Route (http://localhost:3090/dist/app.js:54800:29)

    at Switch (http://localhost:3090/dist/app.js:55002:29)

    at App

    at Router (http://localhost:3090/dist/app.js:54431:30)

    at BrowserRouter (http://localhost:3090/dist/app.js:54048:35)

yjym33님의 프로필

yjym33

질문자

2021.10.12

위 오류는 계속 발생하는것 같습니다.. ㅠㅠ

이건 오류가 아닙니다. 그냥 경고일 뿐입니다.

yjym33님의 프로필

yjym33

질문자

2021.10.12

아 그렇군요.. 그런데 채널 생성은 계속 안되는거 같아요.. 

 

  1. Error: Request failed with status code 404 at createError (http://localhost:3090/dist/app.js:2132:15) at settle (http://localhost:3090/dist/app.js:2406:12) at XMLHttpRequest.onloadend (http://localhost:3090/dist/app.js:1534:7)
    1. isAxiosErrortrue
    2. response:
      1. data"존재하지 않는 워크스페이스입니다."
      2. status404
      3. statusText"Not Found"
    3. message"Request failed with status code 404"
    4. stack"Error: Request failed with status code 404\n at createError (http://localhost:3090/dist/app.js:2132:15)\n at settle (http://localhost:3090/dist/app.js:2406:12)\n at XMLHttpRequest.onloadend (http://localhost:3090/dist/app.js:1534:7)"

 

채널 생성 할때마다 이 오류메세지를 계속 뱉는거 같습니다,..

늦은시간까지 귀찮게 해드려서 죄송합니다.

'http://localhost:3095/api/workspaces/undefined/channels

저기 언디파인드가 들어가는 것은 onCreateChannel에 [workspace] 이런 게 없어서 그럴 수 있습니다.

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

백엔드 쪽이 문제이면 node_modules를 지웠다가 처음 세팅하신 순서대로 npm i 부터 db:seed:all까지 다시 한번 세팅을 해보는게 나을까요?

프론트엔드가 문제입니다. <Route path="..." 여기 코드에서부터 에러가 있을 수 있습니다.

일단 저기가 왜 undefined가 되는지부터 파악해야 합니다. App.tsx 코드 체크해보세요.

지금보니까 주소가

localhost3095

오타네요.

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

그래도 지속적으로 오류가 발생하네요.. ㅠㅠ 

바뀌고 나서는 다른 오류가 생겼습니다..

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

아 이부분을 말씀하신것 같아서 이부분도 수정했습니다.

 

   const onCreateChannel = useCallback(
      (e) => {
        e.preventDefault();
        axios
          .post(
            `http://localhost3095/api/workspaces/${workspace}/channels`,
            {
              name: newChannel,
            },
            {
              withCredentials: true,
            },
          )
          .then((response) => {
            setShowCreateChannelModal(false);
            revalidateChannel();
            setNewChannel('');
          })
          .catch((error) => {
            console.dir(error);
            toast.error(error.response?.data, { position: 'bottom-center' });
          });
      },
      [workspace, newChannel],
    );
 

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

백엔드 과정에서 해당 명렁어를 수행했습니다.. 

기존에도 잘 나왔었는데 이 부분 진행하면서 오류가 계속 뜨는거 같아요..

그리고 

"onCreateChannel의 deps 배열에 [workspace, newChannel]이어야 하는데 workspace가 빠져있네요."

라고 말씀해주셨는데 코드를 봐도 어느부분이 빠진지를 모르겠습니다..  제로초님 깃허브에서 똑같이 가져와서 해당부분 비교했는데 다른부분이 없는것 같아서요..

밑에 말씀드린대로 배열에 추가하세요.

0

백엔드 생성 과정에서 sequelize seed:all 관련 명령어 수행하셨나요?

일단 url이 /api/workspaces/undefined/channels 입니다. 저 부분이 undefined네요.

onCreateChannel의 deps 배열에 [workspace, newChannel]이어야 하는데 workspace가 빠져있네요.

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

그리고 콘솔창에서 지속적으로 404 에러가 발생합니다..

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

CreateChannelModal 부분쪽 코드도 올립니다.

어느 부분이 문제인지를 잘 모르겠습니다.

 

import Modal from "@components/Modal";
import useInput from "@hooks/useInput"; // 커스텀 Hooks
import { Button, Input, Label } from "@pages/SignUp/styles";
import { IChannel, IUser } from "@typings/db";
import fetcher from "@utils/fetcher";
import axios from "axios";
import React, { VFC, useCallback, } from "react";
import { useParams } from "react-router-dom";
import { toast } from "react-toastify";
import useSWR from "swr";

interface Props {
    show : boolean;
    onCloseModal: () => void;
    setShowCreateChannelModal: (flag: boolean) => void;
}

const CreateChannelModal: VFC<Props> = ( {show, onCloseModal, setShowCreateChannelModal }) => {
    const [newChannel, onChangeNewChannel, setNewChannel] = useInput('')
    const { workspace, channel} = useParams<{workspace: string, channel:string}>();
    const { data: userData, error, revalidate } = useSWR<IUser | false>(
        'http://localhost:3095/api/users',
        fetcher,
        {
          dedupingInterval: 2000, // 2초
        }
      );
     
      const { data: channelData, revalidate: revalidateChannel } = useSWR<IChannel[]>(
        userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null,
         fetcher,
      );
    const onCreateChannel = useCallback((e) => {
      e.preventDefault();
      axios
       .post(`http://localhost:3095/api/workspaces/${workspace}/channels`,
          {
          name: newChannel
       },
           {
      withCredentials: true,  
      },
    ).then(() => {
      setShowCreateChannelModal(false);
      revalidateChannel();
      setNewChannel('');
    })
    .catch((error) => {
      console.dir(error);
      toast.error(error.response?.data, {position: 'bottom-center'})
    });
    }, [newChannel]);

    return (
      <Modal show={show} onCloseModal={onCloseModal}>
      <form onSubmit={onCreateChannel}>
        <Label id="channel-label">
         <span>채널</span>
         <Input id ="channel" value={newChannel} onChange={onChangeNewChannel} />
        </Label>
        <Button type="submit">생성하기</Button>
      </form>
    </Modal>
    )
}

export default CreateChannelModal;

0

yjym33님의 프로필

yjym33

질문자

2021.10.12

console 란에서도 아래와 같은 오류로 에러메세지를 뱉습니다.

app.js:1667 POST http://localhost:3095/api/workspaces/undefined/channels 404 (Not Found)

  1. Error: Request failed with status code 404 at createError (http://localhost:3090/dist/app.js:2132:15) at settle (http://localhost:3090/dist/app.js:2406:12) at XMLHttpRequest.onloadend (http://localhost:3090/dist/app.js:1534:7)
    1. isAxiosErrortrue
    2. response:
      1. data"존재하지 않는 워크스페이스입니다."
      2. status404
      3. statusText"Not Found"
    3. message"Request failed with status code 404"
    4. stack"Error: Request failed with status code 404\n at createError (http://localhost:3090/dist/app.js:2132:15)\n at settle (http://localhost:3090/dist/app.js:2406:12)\n at XMLHttpRequest.onloadend (http://localhost:3090/dist/app.js:1534:7)"