해결된 질문
작성
·
167
0
proxy서버를 켜도 404에러가 뜹니다.. 들어가면 존재하지 않는 워크페이스라고 합니다 조언을 얻을 수 있을까요,, 어느 파일에서 잘못된건지 모르겠어요
밑 코드는 workspace 코드입니다. 프록시서버가 안먹혀서 http는 수동으로 다 붙여놓은 상태입니다.
import ChannelList from '@components/ChannelList';
import DMList from '@components/DMList';
import InviteChannelModal from '@components/InviteChannelModal';
import InviteWorkspaceModal from '@components/InviteWorkspaceModal';
import Menu from '@components/Menu';
import Modal from '@components/Modal';
import useInput from '@hooks/useInput';
import {
AddButton,
Channels,
Chats,
Header,
LogOutButton,
MenuScroll,
ProfileImg,
ProfileModal,
RightMenu,
WorkspaceButton,
WorkspaceModal,
WorkspaceName,
Workspaces,
WorkspaceWrapper,
} from '@layouts/Workspace/styles';
import loadable from '@loadable/component';
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, useState, useEffect } from 'react';
import { Navigate, Routes, useParams } from 'react-router';
import { Link, Route } from 'react-router-dom';
import useSWR from 'swr';
import gravatar from 'gravatar';
import { toast } from 'react-toastify';
import CreateChannelModal from '@components/CreateChannelModal';
const Channel = loadable(() => import('@pages/Channel'));
const DirectMessage = loadable(() => import('@pages/DirectMessage'));
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, setNewWorkpsace] = useInput('');
const [newUrl, onChangeNewUrl, setNewUrl] = useInput('');
const { workspace } = useParams<{ workspace: string }>();
const {
data: userData,
error,
mutate,
} = 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 { data: memberData } = useSWR<IUser[]>(
userData ? `http://localhost:3095/api/workspaces/${workspace}/members` : null,
fetcher,
);
const onLogout = useCallback(() => {
axios
.post('http://localhost:3095/api/users/logout', null, {
withCredentials: true,
})
.then(() => {
mutate(false, false);
});
}, []);
const onCloseUserProfile = useCallback((e) => {
e.stopPropagation();
setShowUserMenu(false);
}, []);
const onClickUserProfile = useCallback(() => {
setShowUserMenu((prev) => !prev);
}, []);
const onClickCreateWorkspace = useCallback(() => {
setShowCreateWorkspaceModal(true);
}, []);
const onCreateWorkspace = useCallback(
(e) => {
e.preventDefault();
if (!newWorkspace || !newWorkspace.trim()) return;
if (!newUrl || !newUrl.trim()) return;
axios
.post(
'http://localhost:3095/api/workspaces',
{
workspace: newWorkspace,
url: newUrl,
},
{
withCredentials: true,
},
)
.then(() => {
mutate();
setShowCreateWorkspaceModal(false);
setNewWorkpsace('');
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(() => {
setShowInviteWorkspaceModal(true);
}, []);
if (!userData) {
return <Navigate to="/login" />;
}
return (
<div>
<Header>
<RightMenu>
<span onClick={onClickUserProfile}>
<ProfileImg src={gravatar.url(userData.email, { 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>
<ChannelList />
<DMList />
</MenuScroll>
</Channels>
<Chats>
<Routes>
<Route path="/workspace/channel/:channel" element={Channel} />
<Route path="/workspace/dm/:id" element={DirectMessage} />
</Routes>
</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;
답변 1
0
지금 useSWR 부분도 또 수정하신 건가요? workspace 변수 자리에 :workspace가 들어가 있는 상황입니다. 브라우저의 주소창에 주소가 제대로 나와야합니다. workspace/sleact 이런 식으로요. 그래야 workspace 변수도 sleact가 됩니다.
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, setNewWorkpsace] = useInput('');
const [newUrl, onChangeNewUrl, setNewUrl] = useInput('');
const { workspace } = useParams<{ workspace: string }>();
const {
data: userData,
error,
mutate,
} = 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 { data: memberData } = useSWR<IUser[]>(
userData ? `http://localhost:3095/api/workspaces/${workspace}/members` : null,
fetcher,
);
밑 파일은 login파일입니다. login을 통해서 워크스페이스를 확인하고 있는데, 밑과 같은 주소로 설정시 없는 라우터라고 떠서
아래와 같이 주소를 처리했었습니다.
app.index파일은
다음과 같습니다. 어디서 틀린걸까요,,
아뇨 저렇게 넣지 마시고, Navigate에서는 강좌대로 넣으라는 말씀이었습니다. Route에서만 /* 붙이고요.
Route에서 /workspace/:workspace/* 했으니까
Navigate에서는 /workspace/sleact/channel/일반으로 가는거죠.
sleact가 :workspace에 대응되고, channel/일반이 /*에 대응되는 것이고요.
해당 코드를 강의와 똑같이 진행했는데,, 여기가 틀린게 아니라, app파일을 말씀하시는 걸까요?