인프런 커뮤니티 질문&답변

성창수님의 프로필 이미지
성창수

작성한 질문수

Slack 클론 코딩[실시간 채팅 with React]

워크스페이스 만들기 + 로그아웃하기

Request failed with status code 404

작성

·

5.6K

0

제로초님,

layouts폴더에 App.tsx에서

import React from "react";
import loadable from '@loadable/component';
import { Routes, Route, Navigate } from "react-router-dom";
const LogIn = loadable(() => import("@pages/Login"));
const SignUp = loadable(() => import('@pages/SignUp')); 
const Channel = loadable(() => import('@pages/Channel')); 

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Navigate replace to="/login" />} />
      <Route path="/login" element={<LogIn />} />
      <Route path="/signup" element={<SignUp />} />
      <Route path="/workspace/channel" element={<Channel />} />
    </Routes>
    )
}

export default App;

Route의 4번째줄 path에 /workspace로 하면 로그아웃 할 때 제대로 작동하는데 저렇게 workspace/channel로 코드를 작성하면 로그아웃 할 때, 아래처럼 뜹니다

/를 하나만 붙여야 되는건가요?

나머지 코드들은 변경하지 않았습니다.

Login 폴더 index.tsx

import useInput from "@hooks/useInput";
import axios from "axios";
import React, { useCallback, useState } from "react";
import { Form, Label, Input, LinkContainer, Button, Header, Error} from './styles';
import {Link, Navigate} from 'react-router-dom';
import useSWR from 'swr';
import fetcher from "@utils/fetcher";

const LogIn = () => {
  const {data, error, mutate} = useSWR('/api/users', fetcher);
  const [logInError, setLogInError] = useState(false);
  const [email, onChangeEmail] = useInput('');
  const [password, onChangePassword] = useInput('');
  const onSubmit = useCallback((e: any) => {
    e.preventDefault();
    setLogInError(false);
    axios
    .post(
      '/api/users/login',
      {email, password},
      {withCredentials: true},
    )
    .then((response) => {
      mutate(response.data, false);
    })
    .catch((error) => {
      setLogInError(error.response?.data?.statusCode === 401);
    })
  }, [email, password, mutate]);

  if(data === undefined) {
    return <div>로딩중...</div>
  }

  if(data) {
    return <Navigate to="/workspace/channel" />
  }

  return (
    <div id="container">
      <Header>Sleact</Header>
      <Form onSubmit={onSubmit}>
        <Label id="email-label">
          <span>이메일 주소</span>
          <div>
            <Input type="email" id="email" name="email" value={email} onChange={onChangeEmail} />
          </div>
        </Label>
        <Label id="password-label">
          <span>비밀번호</span>
          <div>
            <Input type="password" id="password" name="password" value={password} onChange={onChangePassword} />
          </div>
          {logInError && <Error>이메일과 비밀번호 조합이 일치하지 않습니다.</Error>}
        </Label>
        <Button type="submit">로그인</Button>
      </Form>
      <LinkContainer>
        아직 회원이 아니신가요?&nbsp;
        <Link to="/signup">회원가입 하러가기</Link>
      </LinkContainer>
    </div>
  );
};
export default LogIn;

 

workspace.tsx

import axios from "axios";
import React, { FC, useCallback } from "react";
import useSWR from 'swr';
import fetcher from "@utils/fetcher";
import { Navigate } from "react-router-dom";

const Workspace: FC<React.PropsWithChildren<{}>> = ({children}) => {
  // revalidate = 서버로 요청 다시 보내서 데이터를 다시 가져옴
  // mutate = 서버에 요청 안보내고 데이터를 수정
  const {data, error, mutate} = useSWR('/api/users', fetcher);

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

  if(data === false) {
    return <Navigate to="/login" />
  }

  return(
    <div>
      <button onClick={onLogout}>로그아웃</button>
      {children}
    </div>
  )
}

export default Workspace;

swr은 2버전입니다.

답변 1

0

성창수님의 프로필 이미지
성창수
질문자

image혹시 몰라서 에러메시지도 첨부했습니다

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

주소가 이상한 걸 볼 수 있습니다.

/api/users/logout 앞에 / 빠뜨리셨네요.

성창수님의 프로필 이미지
성창수
질문자

아 그런거군요 감사합니다!

성창수님의 프로필 이미지
성창수

작성한 질문수

질문하기