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

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

작성한 질문수

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

axios로 요청 보내기와 CORS, proxy

POST http://localhost:3090/api/users net::ERR_INTERNET_DISCONNECTED

작성

·

967

0

제로초님, 코드는 정확히 따라 한 거 같은데, 무엇이 문제인지 판단이 안되네요...

리액트 v18, 타입스크립트 v18, axios는 1.2.3 입니다.

 

webpack

import path from 'path';
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
import webpack, { Configuration as WebpackConfiguration } from "webpack";
import { Configuration as WebpackDevServerConfiguration } from "webpack-dev-server";

interface Configuration extends WebpackConfiguration {
  devServer?: WebpackDevServerConfiguration;
}

import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

const isDevelopment = process.env.NODE_ENV !== 'production';

const config: Configuration = {
  name: 'sleact',
  mode: isDevelopment ? 'development' : 'production',
  devtool: !isDevelopment ? 'hidden-source-map' : 'eval',
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
    alias: {
      '@hooks': path.resolve(__dirname, 'hooks'),
      '@components': path.resolve(__dirname, 'components'),
      '@layouts': path.resolve(__dirname, 'layouts'),
      '@pages': path.resolve(__dirname, 'pages'),
      '@utils': path.resolve(__dirname, 'utils'),
      '@typings': path.resolve(__dirname, 'typings'),
    },
  },
  entry: {
    app: './client',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                targets: { browsers: ['IE 10'] },
                debug: isDevelopment,
              },
            ],
            '@babel/preset-react',
            '@babel/preset-typescript',
          ],
          env: {
            development: {
              plugins: [['@emotion', { sourceMap: true }], require.resolve('react-refresh/babel')],
            },
            production: {
              plugins: ['@emotion']
            }
          },
        },
        exclude: path.join(__dirname, 'node_modules'),
      },
      {
        test: /\.css?$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin({
      async: false,
      // eslint: {
      //   files: "./src/**/*",
      // },
    }),
    new webpack.EnvironmentPlugin({ NODE_ENV: isDevelopment ? 'development' : 'production' }),
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    publicPath: '/dist/',
  },
  devServer: {
    historyApiFallback: true, // react router
    port: 3090,
    devMiddleware: { publicPath: '/dist/' },
    static: { directory: path.resolve(__dirname) },
    proxy: {
      '/api/': {
        target: 'http://localhost:3095',
        changeOrigin: true,
      },
    },
  },
};

if (isDevelopment && config.plugins) {
  config.plugins.push(new webpack.HotModuleReplacementPlugin());
  config.plugins.push(new ReactRefreshWebpackPlugin());
}
if (!isDevelopment && config.plugins) {
}

export default config;

 

index.tsx

import useInput from "@hooks/useInput";
import React, { useCallback, useState } from "react";
import { Form, Label, Input, LinkContainer, Button, Header, Error} from './styles'
import axios from "axios";


const SignUp = () => {
  const [email, onChangeEmail] = useInput('');//useInput은 커스텀 훅
  const [nickname, onChangeNickName] = useInput('');
  const [password, setPassword] = useState('');
  const [passwordCheck, setPasswordCheck] = useState('');
  const [mismatchError, setMismathError] = useState(false);

  const onChangePassword = useCallback((e: any) => {
    setPassword(e.target.value);
    setMismathError(e.target.value !== passwordCheck);
    // 함수 기준으로 외부 변수만 deps에 적어줌 내부 변수는 x
  }, [passwordCheck]);
  const onChangePasswordCheck = useCallback((e: any) => {
    setPasswordCheck(e.target.value);
    setMismathError(e.target.value !== password)
  }, [password]);
  const onSubmit = useCallback((e: React.FormEvent) => {
    e.preventDefault();
    if(!mismatchError && nickname){
      console.log('서버로 회원가입하기');
      axios.post('/api/users', {
        email,
        nickname,
        password,
      })
      .then((response) => {
        console.log(response);
      })//요청이 성공하면 실행
      .catch((error) => {
        console.log(error.response);
      })//요청이 실패하면 실행
      .finally(() => {});//성공하든 실패하든 실행시키고 싶은 것
    }
    console.log(email, nickname, password, passwordCheck)
  }, [email, nickname, password, passwordCheck, mismatchError]);

  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="nickname-label">
          <span>닉네임</span>
          <div>
            <Input type="text" id="nickname" name="nickname" value={nickname} onChange={onChangeNickName} />
          </div>
        </Label>
        <Label id="password-label">
          <span>비밀번호</span>
          <div>
            <Input type="password" id="password" name="password" value={password} onChange={onChangePassword} />
          </div>
        </Label>
        <Label id="password-check-label">
          <span>비밀번호 확인</span>
          <div>
            <Input type="password" id="password-check" name="password-check" value={passwordCheck} onChange={onChangePasswordCheck} />
          </div>
            {mismatchError && <Error>비밀번호가 일치하지 않습니다.</Error>}
            {!nickname && <Error>닉네임을 입력해주세요.</Error>}
            {/* {signUpError && <Error>{signUpError}</Error>} */}
            {/* {signUpSuccess && <Success>회원가입되었습니다! 로그인해주세요.</Success>} */}
        </Label>
        <Button type="submit">회원가입</Button>
      </Form>
      <LinkContainer>
        이미 회원이신가요?&nbsp;
        <a href="/login">로그인 하러가기</a>
      </LinkContainer>
    </div>
  );
};
export default SignUp;

이렇게 따라 한 후에 회원 가입 누르면 아래 같은 화면이 뜹니다.

답변 2

0

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

아 혹시 back 폴더로 가서 npm run dev를 하면 되는건가요??

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

네 맞습니다

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

감사합니다 해결됐습니다!

0

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

백엔드 서버 켜셨나요? 백엔드 서버 콘솔에 에러는 없나요?

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

죄송합니다 백엔드 서버 콘솔이 무슨 말인지 모르겠습니다...
백엔드 서버는 npm run dev를 하면 켜지는거 아닌가요??
imageimagenpm run dev를 터미널에는 오류 없이 작동합니다

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

back 폴더에서 하셔야합니다.

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

작성한 질문수

질문하기