🪁react/react 실습

제로초 slack 강의(새롭게 배운 내용 정리)

하얀성 2024. 7. 1. 16:02

안정성 있는 리액트 개발을 위한 많은 라이브러리와 관련 나누는 방법을 설명한다.

리액트와 타입스크립트의 문법을 배우기보단,

리액트, ts와 다른 많은 라이브러리들을 사용한 개발 과정을 따라해보는 강의다.

 

잘 모르겠으면 이 강의 자료를 꼭 확인하자.

https://github.com/ZeroCho/sleact/blob/master/nest-typeorm/README.md

 

sleact/nest-typeorm/README.md at master · ZeroCho/sleact

Contribute to ZeroCho/sleact development by creating an account on GitHub.

github.com

 


환경설정

 

1. js 빌드와 babel 사용

 

ts -> js로 변환이 가능하지만

ts -> babel -> js로의 변환이 더욱 안정적이고 빠름.

현재 dist로 npm run build를 통해 ts 내용ㅇ

 

2. 주어진 Webpack 설정

  1. TypeScript 컴파일: babel-loader가 TypeScript 파일(.ts, .tsx)을 처리합니다. 이때, @babel/preset-typescript를 사용하여 TypeScript 코드를 JavaScript로 변환합니다.
  2. Babel을 통한 추가 변환: Babel은 @babel/preset-env와 @babel/preset-react를 사용하여 최신 JavaScript 및 React 코드를 변환합니다. 이를 통해 브라우저 호환성을 확보하고, React JSX 문법을 처리합니다.
    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: [require.resolve('react-refresh/babel')],
                },
              },
            },
     
  3. 타입 검사: ForkTsCheckerWebpackPlugin을 사용하여 타입 검사를 별도로 수행합니다. 이는 Babel이 타입 검사를 하지 않기 때문에 필요한 단계입니다.
    plugins: [
        new ForkTsCheckerWebpackPlugin({
          async: false,
          // eslint: {
          //   files: "./src/**/*",
          // },
        }),

따라서, 이 설정은 TypeScript 코드를 직접 JavaScript로 변환하는 대신, Babel을 중간에 끼워서 변환하는 과정을 따릅니다. 이는 최신 JavaScript 기능을 지원하고, 더 나은 빌드 성능과 브라우저 호환성을 제공하기 위함입니다.

 


3.  localhost:3090으로 서버와 소통하지만 뒤에 /login이든, /signup이든 달수있는 이유

devServer 설정의 historyApiFallback: true 옵션이 React Router와 함께 잘 동작하게 해주는 이유는 SPA(Single Page Application)의 라우팅을 지원하기 때문입니다.

devServer: {
    historyApiFallback: true, // react router
    port: 3090,
    devMiddleware: { publicPath: '/dist/' },
    static: { directory: path.resolve(__dirname) },
  },

 


react 사용 시작.

(환경설정이 끝났다면 npm run dev로 실행. cra와 비슷한 과정이다)

 

1. @loadable/component 사용. 

 

@loadable/component는 React의 최신 기능을 완벽하게 지원

 

- 서버 사이드 렌더링(SSR) 지원

@loadable/component는 서버 사이드 렌더링을 쉽게 통합할 수 있습니다.

이는 SEO 향상 및 초기 로딩 시간을 단축하는 데 도움이 됩니다.

 

- 번들 사이즈 최적화

코드 스플리팅을 통해 번들 사이즈를 줄일 수 있습니다. 이는 페이지 로드 속도를 개선하고 사용자 경험을 향상시킵니다.


회원가입 기능

 

- 관련 db내역 등이 콘솔에서 찍히지 않도록 하자.

 

회원가입 등록, 로그인 등의 내용이 network의 payload에서 나오는 것은 괜찮지만,

console에서 나오는 것은 안된다.

 

그러니 왠만해서는 콘솔에 뭐가 나오지 않도록하자.

(내 프로젝트 수정하자.)

mysql에 회원가입 성공내역


- set함수 내역을 비동기에 사용할 경우, 비동기 통신 이전에 초기화 시키자

 

set 관련 내역들을 초기화 해야 연속된 요청시, 이전 내역(이전 요청의 성공, 실패 여부 정보)이 안에 남아 있지 않는다.

 

setSignUpError(''); // 초기화

     setSignUpSuccess(false); // 초기화

const onSubmit = useCallback(
    async (e) => {
      e.preventDefault();
      console.log(email, nickname, password, passwordCheck, mismatchError)
      if (!mismatchError && nickname) {
        console.log('서버로 회원가입하기');
        setSignUpError(''); // 초기화
        setSignUpSuccess(false); // 초기화
        try {
          const response = await axios.post('/api/users', {
            email,
            nickname,
            password,
          });
          console.log(response);
          setSignUpSuccess(true);
          // 데이터 갱신
          mutate('/api/users');
        } catch (error) {
          if (axios.isAxiosError(error)) {
            console.log(error.response);
            setSignUpError(error.response?.data || 'An error occurred');
          } else {
            console.log(error);
            setSignUpError('An unexpected error occurred');
          }
        }
      }
    },
    [email, nickname, password, passwordCheck, mismatchError],
  );

 

 


로그인

 

<Link>는 <a>와 다르게 새로고침을 하지않고 링크를 불러와준다.

 

그러니 새로고침해서 랜더링을 다시 해야하는 <a>태그보다 훨씬 빠르다.

그래서 react에서는 a대신 Link를 사용.

<Link to="/login">로그인 하러가기</Link>

 

정상적으로 회원가입 된대로 로그인  요청이 잘간모습.

 


SWR과 React Query는 중간 저장 상태를 관리하기 위해 만들어진 라이브러리

 

SWR과 React Query: 클라이언트 측 데이터 패칭, 캐싱 및 동기화에 초점을 맞춘 라이브러리

 

이렇게 fetcher 함수와 함께 사용하는 것이 일반적인 swr의 사용법.

import useSWR from 'swr';

const fetcher = url => fetch(url).then(res => res.json());

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher);

  if (error) return <div>Failed to load</div>;
  if (!data) return <div>Loading...</div>;

  return <div>Hello, {data.name}</div>;
}

하지만 요즘 대세는 react-query !!

import { useQuery } from 'react-query';

const fetchUser = async () => {
  const res = await fetch('/api/user');
  return res.json();
};

function Profile() {
  const { data, error, isLoading } = useQuery('user', fetchUser);

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error loading data</div>;

  return <div>Hello, {data.name}</div>;
}

 


swr을 통한 여러 화면 navigate하기.

 

- swr을 통한 로그인 데이터 관리와 상태관리를 통한 화면 route 관리

 

swr을 통한 상태관리. 처음에 data=false로 시작했다가, 로그인 되어서 fetcher 을 통해 로그인 data를 불러왔을 경우,

data는 true가 됨으로 login페이지나, signup 페이지에서는 모두 상태가 로그인된 코드로 바뀌어서 메인 페이지로 날려주는 Redirect를 수행.

 

반면 workspace에서는 로그인도 안된 상황일 때, 들어오면 안되니까 바로 login화면으로 쫒아보낸다.

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

 

 

login , signup 화면에서도 로그인한 상태에서 들어갔을 경우 같은 상황도 고려.

if (data) {//로그인한 상태에서 들어가려고 하는 경우, 바로 메인화면으로 날리기
    return <Redirect to="/workspace/channel" />;
  }

 


- return은 항상 hooks보다 아래에 있어야 한다.

 


- 2024. 7.3 평가

이전 express 서버와 프론트로 만든 경험, cors를 proxy로 제어해본 경험이 있어 잘 따라갔다. 

내가 위에서 기록한 내용들 처럼 프론트 작성시, 추가적인 스킬, 디테일 사항을 잘 말씀해주시니 도움이 많이된다. 

그리고 node, db , 서버 베포하며 머리 쥐어 뜯어본 경험이 이거 배울 때 굉장히 도움이 많이 된다.

(경험이 없었으면 중간에 포기햇을듯. 자료가 조금은 오래되어 불친절한 감이 없잖아 있다. 하지만 잘 따라갈수 있다.)