inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

axios로 요청 보내기와 CORS, proxy

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

1099

성창수

작성한 질문수 14

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;

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

웹팩 react Socket.io socket.io typescript 클론코딩 babel 클론코딩

답변 2

0

성창수

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

0

제로초(조현영)

네 맞습니다

0

성창수

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

0

제로초(조현영)

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

0

성창수

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

0

제로초(조현영)

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

기본 셋팅과 관련하여

0

91

1

초기 셋팅 back과 front만 남겨두고 다 지운 후 진행 방법

0

96

2

focus 시에만 화면 업데이트 되는 이유 + 해결방법

0

149

2

useEffect 개수 관리

0

109

2

라이브러리 서치 방법

0

103

2

함수 정의 패턴

0

77

1

npm run dev 에러

0

152

3

npx webpack 후 에러

0

178

2

'void' 형식 식의 truthiness를 테스트할 수 없습니다.ts(1345)

0

143

2

사용자 가입시 에러발생 (TypeError: Cannot read properties of null (reading 'addMembers')

1

177

2

초기세팅중 packge.json 에러떠요

0

154

2

CORS - Access-Control-Allow-Origin 누락 문제

0

430

3

로그인 페이지 무한 새로고침 현상

0

598

2

Module not found: Error: Can't resolve './App' 에러

0

952

1

배포 방법

0

296

2

npm run dev 시 빌드가 매우 느려졌습니다

0

988

2

alias 경로 설정 오류

0

448

2

fetcher 함수의 data 값이 두번 찍히는 이유

0

275

1

제네릭 질문

0

217

2

ts-node 대신 tsx 사용여부

0

373

1

배포 관련 질문

0

247

1

[nginx + https] 서비스를 실행하면 niginx가 아닌 서비스 화면을 보여주게 하고 싶습니다.

0

385

2

[배포하기] webpack에 aws 퍼블릭 IPv4 주소 와 포트 주소를 작성하고 나서 빌드후 실행하면 오류가 발생합니다.

0

336

1

users 호출 시 쿠키가 담기지 않는 이슈 질문드립니다.

0

247

2