Vite란?

공식문서에 따르면 프랑스어로 빠르다를 의미하고, 빠르고 간결한 모던 웹 프로젝트 개발 경험에 초점을 맞춰 탄생한 빌드 도구이다.

  • 개발 시 네이티브 ES Module을 넘어 더욱 다양한 기능을 제공한다.
  • 번들링 시, Rollup 기반의 다양한 빌드 커맨드를 사용할 수 있습니다. 이는 높은 수준으로 최적화된 정적(static) 리소스들을 배포할 수 있게끔 하며, 미리 정의된 설정(Pre-configured)을 제공합니다.

Create React App대신 사용하는 이유

CRA는 JavaScript로 구성된 Webpack을 사용하는데 속도가 느린편입니다. 평소에는 못느낄 수 있지만 처리해야 할 코드의 양이 많아질 수록 느린 속도를 채감할 수 있습니다.
위와 같은 단점을 해결하기 위해 Esbuild를 기반으로 만들어진 빌드툴인 Vite를 사용하게 됩니다.

*Esbuild: Go 언어로 작성된 JavaScript 빌드툴로 속도가 빠르다.

지원중인 템플릿

  • vanilla
  • vue
  • react
  • preact
  • lit
  • svelte

Vite 설치하기

아래와 같은 명령어를 입력하여 설치할 수 있습니다.
Vite를 사용하기 위해서는 14.18+, 16+의 Node.js를 요구하며 템플릿에 따라 더 높은 버전의 Node.js를 요구할 수 있습니다.

npm create vite@latest

yarn create vite

템플릿 생성하기

React로 작성을 할 것이기 때문에 템플릿 명으로 react를 작성하면 됩니다.
TypeScript의 경우 템플릿-ts를 붙여작성하게 됩니다.

# npm 6.x
npm create vite@latest ${디렉터리 명} --template ${템플릿 명}

# npm 7+
npm create vite@latest ${디렉터리 명} -- --template ${템플릿 명}

# JavaScript react 템플릿 생성
npm create vite@latest vite-test -- --template react

# TypeScript react-ts 템플릿 생성
npm create vite@latest vite-test -- --template react-ts

Vite 실행

npm run dev

참고자료

'Coding > React & React-native' 카테고리의 다른 글

[React] React Hook Form과 yup을 사용한 유효성 검사  (0) 2022.11.21
[Redux] Redux-toolkit  (0) 2022.11.21
[Redux]React-redux 사용하기  (0) 2022.10.25
[React] Portals  (0) 2022.07.16
[React] Fragment  (0) 2022.07.12

Redux?

상태를 전역적으로 관리하기 위해서 사용되는 상태관리 도구이며, Redux 외에도 MobX, React Context, Recoil 등이 있습니다.
상태관리 도구를 사용하여 Props drilling 이슈를 해결할 수 있습니다.

Props drilling?
상태가 존재하는 컴포넌트에서 자식 컴포넌트로 이동을 할 때, 수많은 props를 계속해서 내려야하는 경우를 말하며, 코드의 가독성이 나빠지고 유지보수 또한 힘들어집니다.

Action

상태에 어떤 Action(행동)을 취할 것인지 정해놓는 객체입니다.
Action이 많아질 경우 ActionTypes 파일을 생성하여 타입을 모아두는 경우도 있습니다.
Action 타입을 정의할 때는 모두 대문자로 Snake Case로 작성합니다.

// 전달 받을 값(payload)가 없을 경우
export const loginSuccess = () => ({
  type: "LOGIN_SUCCESS"
})

// 전달 받을 값(payload)가 있을 경우
// payload는 주로 단일 데이터, 객체로 받습니다.
export const loginInfo = (res) => ({
  type: "LOGIN_INFO",
  payload: res
})

Reducer

Dispatch에서 전달받은 Action(행동) 객체의 type에 따라서 상태를 변경시키는 함수입니다. Reducer가 여러개 일 경우 combineReducers를 사용하여 하나로 묶어줄 수 있습니다.

Store

상태가 관리되는 오직 하나뿐인 상태 저장소의 역할을 합니다.
createStore을 사용할 경우 toolkit을 사용하라는 의미로 밑줄이 그어집니다.

import { createStore } from "redux";
import rootReducer from "./redux/reducers";

// Reducer를 연결한다.
const store = createStore(rootReducer);

export default store;

React-redux 초기 세팅

redux 라이브러리 설치

React에서 Redux를 사용하기 위해서는 redux, react-redux를 모두 설치해야 합니다.
아래의 코드에서 @reduxjs/toolkit은 후에 react-toolkit을 사용하기 위해 설치한 것입니다.

npm install @reduxjs/toolkit redux react-redux

파일 구조 생성

redux-test
└─ src
   ├─ App.js     메인화면
   ├─ Compo1.js  프롭받을 컴포넌트
   ├─ Compo2.js  프롭받을 컴포넌트
   ├─ index.css
   ├─ index.js
   ├─ redux
   │  ├─ actions  액션 정의
   │  │  └─ login.js
   │  └─ reducers 상태 변경 함수
   │     ├─ index.js
   │     └─ loginReducer.js
   └─ store.js    상태 저장소

Actions 폴더 생성

  • 액션에 관한 파일 생성
  • 액션 타입과 액션을 각각의 파일로 생성해도 무관하다.
// login.js
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
export const LOGIN_INFO =  "LOGIN_INFO";

export const loginSuccess = () => ({
  type: LOGIN_SUCCESS
})

export const loginInfo = (res) => ({
  type: LOGIN_INFO,
  payload: res
})

Reducers 폴더 생성

  • 리듀서를 정의할 파일 생성
// index.js
import { combineReducers } from "redux";
import loginReducer from "./loginReducer";

// 여러 리듀서들을 하나로 묶어준다.
const rootReducer = combineReducers({
  loginReducer,
});

export default rootReducer;

// loginReducer.js
import { LOGIN_SUCCESS, LOGIN_INFO } from "../actions/login";

// 초기 상태 지정
const initialstate = {
  isLogin: false,
  userName: "",
};

// 초기 상태 불변성
const loginReducer = (state = initialstate, action) => {
  switch (action.type) {
    case LOGIN_SUCCESS:
      return {
        // 순서 중요
        ...state,
        isLogin: true,
      };
    case LOGIN_INFO:
      return {
        isLogin: true,
        userName: action.payload,
      };
    default:
      return state;
  }
};

export default loginReducer

루트 폴더 src폴더에 store.js 파일 생성

  • store.js: 상태가 저장되는 저장소
// store.js
// 취소선: redux toolkit 사용하란 의미
import { createStore } from "redux";
import rootReducer from "./redux/reducers";

const store = createStore(rootReducer);

export default store;

Redux 상태 사용하기

Redux의 상태를 변경 및 불러오기 위해서는 useDispatch, useSelector가 필요합니다.

useDispatch

Reducer를 호출하여 Action을 전달해주는 함수이다. 전달인자로는 Action의 객체가 전달된다.
useDispatch를 사용하기 위해서는 변수에 할당해 준뒤 사용할 수 있다.

import { useDispatch } from "react-redux";
import { loginInfo, loginSuccess } from "./redux/actions/login";

// 사용하기위해 변수에 할당(함수형식)
const dispatch = useDispatch();

// 전달인자가 없을 경우
dispatch(loginSuccess());

// 전달인자가 있을 경우
dispatch(loginInfo("homil2"));

useSelector

컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 해주는 메서드이다.
함수내에서는 사용할 수 없다.

import { useSelector } from "react-redux";

// 위에서 정의한 loginReducer의 상태 값을 객체로 받아온다.
useSelector((state) => state.loginReducer)

실사용

로그인 버튼 클릭시 로그인상태가 유지되며 유저네임을 작성후 전송하면 해당 유저의 이름이 같이 담기도록 하는 코드를 구현했다.

// app.js
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { loginInfo, loginSuccess } from "./redux/actions/login";

const App = () => {
  const dispatch = useDispatch();
  const [name, setName] = useState("");

  const nameChange = (el) => {
    setName(el)
  };
  console.log(useSelector((state) => state.loginReducer))

  const loginBtnClick = () => {
    dispatch(loginSuccess())
    dispatch(loginInfo(name))
  };

  return (
    <div className="container">
      <div>
        <label htmlFor="name">이름</label>
        <input id="name" onChange={(el) => nameChange(el.target.value)}></input>
      </div>
      <div>
        <button type="button" onClick={loginBtnClick}>
          로그인
        </button>
      </div>
    </div>
  );
};

export default App;

// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

'Coding > React & React-native' 카테고리의 다른 글

[Redux] Redux-toolkit  (0) 2022.11.21
[React] Vite를 사용해보자  (0) 2022.10.25
[React] Portals  (0) 2022.07.16
[React] Fragment  (0) 2022.07.12
[React] React 디버깅  (0) 2022.07.08

Portals

Fragment를 사용하면 깔끔한 코드를 작성할 수 있습니다.

React Portals은Fragment와 비슷한 일을 하여 간결한 코드를 작성하는데 사용됩니다.

부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링 하는 최고의 방법입니다.

ReactDOM.createPortal(child, container)

첫 번째 인자 child는 엘리먼트, 문자열, fragment와 같은 어떤 종류이든 렌더링할 수 있는 React자식 요소입니다.

두 번째 인자 container는 DOM 엘리먼트입니다.

사용법

일반적인 컴포넌트 렌더링 메서드에서 요소를 반환할 때, 해당요소는 부모 노드에서 가장 가까운 자식으로 연결됩니다.

portal의 전형적인 동작 방법은 부모 컴포넌트에 overflow: hidden이나 z-index가 있는 경우 이지만, 시각적으로 자식을 보여줘야 하는 경우가 있습니다. (다이얼로그, 호버카드, 툴팁, 모달 등)

// 일반적인 렌더링 방법
render(){
	return (
    	<div>
        	{this.props.children}
        </div>
    );
}

// Portal을 이용한 렌더링 방법
render(){
	return ReactDOM.createPortal(
    	this.props.children,
        domNode
    );
}

참고자료

https://ko.reactjs.org/docs/portals.html

 

Portals – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

'Coding > React & React-native' 카테고리의 다른 글

[React] Vite를 사용해보자  (0) 2022.10.25
[Redux]React-redux 사용하기  (0) 2022.10.25
[React] Fragment  (0) 2022.07.12
[React] React 디버깅  (0) 2022.07.08
[Redux] Redux?  (0) 2022.07.01

React.Fragment란?

DOM에 별도의 노드를 추가하지 않고 여러 자식 요소를 그룹화할 수 있습니다.

JSX 제한 사항

JSX 코드를 작성할 때 Root 요소가 존재하지 않고 나란히 존재하고 있다면 JSX 문법에 위반하는 행위가 됩니다.

아래의 코드와 같이 JSX는 ReactDOM 요소로 작성이 가능합니다. 한개의 Root 요소 안에는 여러개의 요소가 존재할 수 있지만 Root 요소는 여러개가 존재할 수 없다는 것입니다.

// JSX 문법에러
return (
    <h2>안녕하세요 여러분!!</h2>
    <p>만나게 되어 반갑습니다!</p>
);

// JSX 문법을 ReactDOM으로 변경한 코드
return (
	React.createElement('h2' {}, '안녕하세요 여러분!')
	React.createElement('p' {}, '만나게 되어 반갑습니다!')
);

JSX 제한 사항 해결 방안

이를 해결하기 위해서 <div>태그를 사용하는 경우 디자인 작업을 할 때 작업속도가 느려지기 때문에 대신 사용하는 것이 바로 Fragment 입니다. Fragment를 사용할 경우 아무것도 없는 요소라고 JSX문법은 판단을 하지만 Root 요소라고 판단을 하기도 합니다.

또한, div를 남발하여 사용할 경우 불필요한 div가 화면에 모두 렌더링 됩니다.

// <div>를 통한 JSX 문법 에러 해결
return (
    <div>
        <h2>안녕하세요 여러분!!</h2>
        <p>만나게 되어 반갑습니다!</p>
    </div>
);


// Fragment를 통한 JSX 문법 에러 해결
return (
    <React.Fragment>
        <h2>안녕하세요 여러분!!</h2>
        <p>만나게 되어 반갑습니다!</p>
    </React.Fragment>
);

// Fragment 단축 문법
return (
    <>
        <h2>안녕하세요 여러분!!</h2>
        <p>만나게 되어 반갑습니다!</p>
    </>
);

'Coding > React & React-native' 카테고리의 다른 글

[Redux]React-redux 사용하기  (0) 2022.10.25
[React] Portals  (0) 2022.07.16
[React] React 디버깅  (0) 2022.07.08
[Redux] Redux?  (0) 2022.07.01
[React] React 시작하기 (create-react-app)  (0) 2022.06.24

리액트 에러 발생

React server를 실행하고 있을 때, 콘솔에서 에러 코드가 나오지만 웹페이지에서도 콘솔창과 동일한 에러 코드가 나옵니다.

에러코드와 함께 해결할 수 있는 방향을 제시해줍니다. 해당 에러 코드 조각과 해결 방안을 통해 프로그램을 디버깅* 할 수 있습니다.

이렇기 때문에 항상 콘솔에 나오는 에러 코드를 확인해야 합니다.

자주 발생하는 에러

JSX 요소 규칙

  • JSX로 작성한 요소를 하나의 루트 요소로 감싸주어야 합니다.
  • 이때, 쓸모없는
  • 태그로 감싸줄 시 디자인 요소에 방해가 될 수 있습니다.
  • 이것은 React.fragment(<></>)를 사용하여 하나의 루트 요소로 감싸주어 에러를 해결할 수 있습니다.

함수명 오타

  • State를 관리하는 함수를 자주 사용해야 하는 만큼 함수명이 많아짐에 따라 오타를 잘 체크해야 합니다.

코드의 흐름 및 경고 분석

  • 컴파일 오류를 일으키지 않아 에러 코드를 볼 수 없는 경우가 있습니다. 이러한 경우 코드 로직을 하나씩 찾아가며 체크를 해야 합니다.
  • 코드 로직을 하나하나 찾아가면 시간이 많이 걸리기 때문에 다른 방법으로 개발자 도구를 켜서 Console 창을 확인하면 어떠한 경고가 나오고 있는지 어떤 파일의 몇 번째 줄에 문제가 있는지 알 수 있습니다.

중단점(breakpoint) 작업하기

  • 개발자 도구의 Source 탭에 가면 소스파일이 있는 경로를 확인할 수 있습니다.
  • 확인하고 싶은 파일을 클릭하여 파일을 실행시키고 코드를 선택한 부분에서 작업을 정지할 수 있으며, 함수의 흐름에 따라 코드를 찾아가며 확인할 수 있습니다.
  • Source탭에서 나온 코드를 수정하여 에러의 유무를 확인할 수도 있습니다.

React DevTools 사용하기

  • 크롬에서 사용할 수 있는 플러그인 중 React Developer Tools을 사용하면 컴포넌트의 트리 구조를 볼 수 있습니다.
  • 해당 컴포넌트를 클릭하면 props로 넘어오는 값과 각종 요소를 확인할 수 있습니다.
  • 특히 가장 좋은 부분은 state의 값을 확인할 수 있다는 것입니다.

*디버깅?

프로그램 개발 단계 중에서 발생하는 오류나 버그를 찾아내고 그 원인을 밝히고 수정하는 작업입니다.

참고자료

  • udemy: 【한글자막】 React 완벽 가이드 with Redux, Next.js, TypeScript

'Coding > React & React-native' 카테고리의 다른 글

[React] Portals  (0) 2022.07.16
[React] Fragment  (0) 2022.07.12
[Redux] Redux?  (0) 2022.07.01
[React] React 시작하기 (create-react-app)  (0) 2022.06.24
[React] React?  (0) 2022.06.09

Redux?

Redux는 전역 상태 관리 라이브러리이다.

Redux와 같은 라이브러리로는 Mobx, Recoil, Ovemind.js가 있다. 가장 많이 사용되는 것은 Redux이며, 다음으로 Mobx가 있었는데 Recoil이 등장하면서 점점 사용율이 밀리는 추세이다.

Redux를 사용하는 이유

1. 모든 컴포넌트가 props 없이 state를 직접 꺼낼 수 있다.

  • 상위 컴포넌트에서 하위 컴포넌트로 state를 넘겨야 하는 데 하위 컴포넌트가 너무 많을 경우 사용
  • state를 보관하는 파일을 하나 만들어서 state를 다 보관하여 모든 컴포넌트들이 props 없이 꺼내서 쓸 수 있다.

2. 상태(state) 관리하기 용이하다.

  • 모든 컴포넌트에서 state를 변경하기 시작할 경우 버그가 생기면 모든 컴포넌트에서 에러를 찾아야한다. 하지만, redux를 사용할 경우 state를 보관하는 장소에서 수정 방법까지 지정해두고 컴포넌트에서 수정방법을 요청(요청만 가능)하면 state가 변한다.
  • 그렇기 때문에 버그가 발생할 경우 state보관 장소에서 찾아서 해결할 수 있다.

Redux의 구조

Action

  • state를 바꾸는 방식을 설정한다.
  • type을 지정하여 Action 객체가 어떤 동작을 하는지 역항르 명시해 주어야합니다.
  • 대문자와 Snake Case로 작성합니다.
  • 필요에 따라 payload를 작성해 구체적인 값을 전달합니다.

Dispatch

  • Reducer로 Action을 전달해주는 함수입니다.
  • Action에 동작을 요청하는 것으로 Action 객체를 파라미터로 받는다.

Reducer

  • Dispatch에게서 전달받은 Action 객체로 변화를 일으키는 함수로 Action 객체의 type에 따라 상태를 변경하는 함수입니다.
  • Reducer는 외부 요인으로 인해 값이 변경되는일이 없는 순수함수여야 합니다.

Store

  • 상태가 관리되는 오직 하나뿐인 저장소의 역할을 합니다.
  • Redux의 상태가 저장되어 있는 공간입니다.

Redux의 동작 과정

Action → Dispatch → Reducer → Store

  1. Action을 정의한다.
  2. Dispatcher에서 Aciton객체를 파라미터로 받아 Reducer 함수로 전달한다.
  3. Reducer 함수는 Action 객체의 값을 확인하고, 그 값에 따라 전역 상태 저장소(Store)의 상태를 변경한다.

참고자료

'Coding > React & React-native' 카테고리의 다른 글

[React] Portals  (0) 2022.07.16
[React] Fragment  (0) 2022.07.12
[React] React 디버깅  (0) 2022.07.08
[React] React 시작하기 (create-react-app)  (0) 2022.06.24
[React] React?  (0) 2022.06.09

+ Recent posts