210122 TIL #React

이예주·2021년 1월 22일
0

Today I Learned

목록 보기
2/10

React

웹 게임을 만들며 배우는 React(2)

클래스의 개념이 조금 잡히기 시작하니 클래스를 쓰지 말란다. 아무튼 클래스 사용을 지양하기 위해 나온 것이 React Hooks. 함수 형태로 사용 가능하다. 코드가 훨씬 짧고 간결하다. 클래스 대신 컴포넌트로, state를 객체로 쓰는 대신 하나씩 사용하기. 클래스를 사용하든 Hooks를 사용하든 개인의 취향에 달려있지만 React는 Hooks를 권장하고 있다.

/* Class */
this.state = {
  first: Math.ceil(Math.random() * 9),
  second: Math.ceil(Math.random() * 9),
  value: '',
  result: ''
};

/* Hooks */
const [first, setFirst] = React.useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = React.useState(Math.ceil(Math.random() * 9));
const [value, setValue] = React.useState('');
const [result, setResult] = React.useState('');

클래스와 Hooks의 state 선언 비교. Hooks는 useState처럼 use로 시작하는 함수를 사용한다.

webpack 공식문서

페이지 하나를 살펴봐도 컴포넌트가 수십, 수백개가 들어간다. 페이스북 개발자가 밝힌 바로는 페이스북에 사용된 컴포넌트가 약 2만 개. 끝도 없이 증식하는 컴포넌트를 유지보수하기란 은하수에서 B612 찾기와 같다. 이런 중복을 없애기 위해 여러 개의 js 파일을 하나의 파일로 만들어주기 위한 기술이 웹팩이다.

웹팩을 사용하기 위해서는 node 설치가 필요하다. macOS에서 설치법은 다음과 같다.

brew install node		//node, npm 설치
node -v
npm -v				//node, npm 버전 확인

/* 작업 중인 폴더로 이동한 뒤 */
npm init			//package.json을 생성한다.
npm i react react-dom		//리액트와 리액트돔 설치
npm i -D webpack webpack-cli	//웹팩 설치

-D는 개발용을 의미한다. package.jsondependencies가 아닌 devDependencies에 저장된다. 즉, 클라이언트에 배포할 때는 웹팩이 필요하지 않기 때문에 굳이 넣지 않는다.

웹팩의 설정은 기본적으로 webpack.config.js 파일에서 모두 이루어진다. 위 파일을 만들어 config 설정을 하면 자동으로 읽어온다.

const path = require('path');

module.exports = {
  mode: 'development',
  devtool: 'eval',    //프로덕션용: hidden-source-map
  resolve: {
    extensions: ['.jsx', '.js'],
  },
  entry: {
    app: './client',
  },
  module: {
    rules: [{
      test: /\.jsx?$/,
      loader: 'babel-loader',
      options: {
      presets: ['@babel/preset-env', '@babel/preset-react'],
      },
    }],
  },
  output: {
  path: path.join(__dirname, 'dist'),
  filename: 'app.js',
  },
};

modedevtool은 개발용인지 배포용인지에 따라 설정값이 다르다. 개발용일 경우에는 각각 developmenteval을, 배포용일 때에는 productionhidden-source-map을 사용한다.

resolve는 합칠 파일의 확장자를 관리한다. extensions에 확장자를 추가하면 entry에 파일명을 적을 때 확장자를 생략할 수 있다. 위의 코드에서는 .jsx.js 확장자를 추가했다.

entry는 쉽게 말하자면 웹팩을 하려는 파일을 입력하는 곳이다.

/* client.jsx */
const React = require('react');
const ReactDOM = require('react-dom');

const GuGuDan = require('./GuGuDan');

ReactDOM.render(<GuGuDan />, document.querySelector('#root'));

client.jsx를 입력하면 코드를 읽어 module에 있는 설정들을 적용한 뒤, output에 설정된 파일로 합쳐져 출력된다.

moduleentry에서 입력된 파일들의 여러가지 설정을 할 수 있는 곳이다. optionspreset은 여러 plugin의 모음이라고 할 수 있다. 위 코드에서 @babel/preset-env 경우에는 브라우저의 설정에 맞게 자동으로 변환해주는 모듈이다. 기본적으로 preset 안에 모듈 이름만 넣으면 모든 설정을 가져오지만, 특정 설정만 하고 싶을 경우에는 다음과 같이 사용하면 된다.

['@babel/preset-env', {
  targets: {
    browsers: ['> %5 in KR', 'last 2 chrome versions'],
  },
  debug: true,
}],

모듈을 배열로 감싸준 뒤, 첫번째 인덱스에 사용하고자 하는 모듈의 이름을 넣고, 두번째 배열에 설정값을 넣는다. @babel/preset-env 경우에는 브라우저의 설정을 버전별로 관리할 수 있으므로 last 2 chrome versions를 입력한다면 최신 두 버전만 지원한다는 뜻이다. 브라우저 리스트

추가 팁
코드를 수정해야할 때마다 웹팩을 다시 실행시켜야하는데 자동으로 웹팩을 리로딩시키는 플러그인이 있다. npm으로 react-refresh@pmmmwh/react-refresh-webpack-plugin을 설치하면 된다. webpack-dev-server는 개발용 서버이므로 같이 설치해주는 게 좋다. 단, 사용하기 위해서는 package.json의 script에 webpack serve --env development를 추가해준다.

변경된 webpack.client.js
const path = require('path');
const { webpack } = require('webpack');
// refresh를 위한 모듈 추가
const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

module.exports = {
  name: 'wordrelay-setting',
  mode: 'development',    
  devtool: 'eval',
  resolve: {
    extensions: ['.js', '.jsx']
  },
  entry: {
    app: ['./client'],
  },
  module: {
    rules: [{
      test: /\.jsx?/,
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', {
            targets: {
              browsers: ['> 1% in KR'],
            },
            debug: true,
          }],
           '@babel/preset-react',
        ],
        plugins: [
          '@babel/plugin-proposal-class-properties',
          'react-refresh/babel',	//추가
        ],
      },
    }],
  },
  plugins: [
    new RefreshWebpackPlugin()	//추가
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
    publicPath: '/dist/',
  },
  devServer: {		//서버 설정 추가
    publicPath: '/dist/',
    hot: true,
  },
}

핫 리로딩의 장점은 기존 데이터가 유지된다는 것이다.

profile
🏫Chung-Ang Univ. 👩‍💻Computer Science

0개의 댓글