리액트 빠르게 시작하기

서한준·2020년 1월 12일
0

개인적인 스터디 용도로 작성 중이며,
빠른 시일 내로 업데이트할 예정입니다.

1. 시작하기 전, 개발환경 셋팅
2. 리액트의 생명주기 ( Life Cycle )
3. 리액트 + 리덕스
4. 리액트 훅

1. 시작하기 전, 개발환경 셋팅

  1. node.js LTS 버전 설치
  2. yarn 설치
  3. VsCode 설치
  4. VsCode Extensions 설치
    4-1. Import Cost ( 패키지 사이즈 플러그인 )
    4-1. ESLint
    // eslint설정 파일인 .eslintrc 생성
    
    {
      "parser": "babel-eslint",
      "env": {
        "browser": true,
        "es6": true,
        "commonjs": true
      },
      "globals": {
        "process": true
      },
      "extends": ["airbnb"],
      "parserOptions": {
        "ecmaVersion": 6,
        "ecmaFeatures": {
          "jsx": true
        },
        "sourceType": "module"
      },
      "plugins": ["react", "jsx-a11y", "import"],
      "rules": {
        "jsx-a11y/anchor-is-valid": [
          "error",
          {
            "components": ["Link"],
            "specialLink": ["hrefLeft", "hrefRight"],
            "aspects": ["invalidHref", "preferButton"]
          }
        ],
        "linebreak-style": 0,
        "react/prefer-stateless-function": 0,
        "react/jsx-filename-extension": 0,
        "react/jsx-one-expression-per-line": 0,
        "react/prop-types": 0,
        "react/jsx-uses-vars": [2],
        "react/jsx-no-undef": "error",
        "no-console": 0
      }
    }
4-2. Prettier
    // prettier 설정파일인 .prettierrc 생성
    {
      "singleQuote": true,
      "semi": true,
      "useTabs": false,
      "tabWidth": 2,
      "trailingComma": "all",
      "printWidth": 80
    }
  1. 프로젝트 생성
    5-1. yarn global add create-react-app
    5-2. create-react-app todoList
    5-3. yarn add node-sass
    5-4. yarn add --dev prettier-eslint
    5-5. yarn add eslint-config-airbnb

2. 리액트의 생명주기 ( Life Cycle )

참조
https://reactjs.org/docs/react-component.html
http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

이하, 리액트 공식문서의 내용을 아주 짧게 요약하였으며
위 링크에 접속하여 직접 읽어볼 것을 권장합니다.

2-1. constructor

// 생성자. 여기에서 선언할 state는 props로 내려받는 값 보다는, default로 정의할 값을 설정하는게 좋다.

constructor(props) {
  super(props);
  this.state = {
    count: 0,
    productList: [],
    showPopup: false,
  }
}

2-2. componentDidMount

// 1. 데이터 호출해야 하는 경우
// 2. 화면이 한 번 그려지고나서 호출되기에, 크기나 위치에 따라 DOM Node를 체크해야 하는 경우

componentDidMount() {
  this.getDataList();
}

getDataList = async() => {
  await axios.get('https://blahblah.com/');
}

2-3. componentDidUpdate

// 이전의 값과 지금의 값을 비교하여 무언가를 실행해야 할 경우
// ( ex. 상품A의 상세페이지에서 상품B의 상세페이지로 이동할 경우,
// 상품 id값의 변동을 확인하여 id값으로 상세페이지에 노출할 데이터만 갱신해줌으로써 화면의 일부를 새로 그린다. )
// [ Warrning ] : 잘못 사용할 경우, 무한루프가 발생하므로 유의할 것!!

componentDidUpdate(prevProps) {
  if(this.props.productId !== prevProps.productId) {
    this.getProductItem(prevProps.productId);
  }
}

2-4. componentWillUnmount

// 컴포넌트가 삭제되기 바로 직전에 실행되며, clearTimeout 등의 이벤트 제거에 사용된다.

componentWillUnMount() {
  clearTimeout(foobar);
}

2-5. shouldComponentUpdate

// 이전의 값과 지금의 값을 비교하여 특정조건에 따라 랜더링을 막을 수 있다.
// ( ex. 검색페이지에서 검색버튼을 누르기 전에 검색 필터가 바뀌더라도 랜더링을 다시 안할 수 있다. )

shouldComponentUpdate(nextProps, nextState) {
  if(nextProps.item === nextState.item){
    return false;
  }
  
  return true;
}

2-6. getDerivedStateFromProps

// props에서 받아온 값을 state에 동기화시킬 경우
// ( ex. 헤더 컴포넌트에 로그인 정보가 props로 받아질 경우, state에 저장 및 닉네임 노출 )

getDerivedStateFromProps(props, state) {
  if(props.value !== state.value){
    return {
      user: props.value,
    };
  }
  
  return null;
}

2-7. getSnapshotBeforeUpdate

// 여기서 반환된 값은 componentDidUpdate의 3번째 인자인 snapshot으로 전달됩니다.
// 주로 스크롤 위치를 가져올 때 사용

getSnapShotBeforeUpdate(prevProps, prevState) {
  if (prevProps.list.length < this.props.list.length) {
    const list = this.listRef.current;
    return list.scrollHeight - list.scrollTop;
  }
  return null;
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
    const list = this.listRef.current;
    list.scrollTop = list.scrollHeight - snapshot;
  }
}

3. 리액트 + 리덕스

3-1. Action

Action이란, Store에 정보를 전달하기 위한 데이터 묶음으로
이벤트를 구분할 수 있는 식별자와 해당 이벤트의 실행에 필요한 값을 함께 가지고 있는 객체입니다.

{
  type: "식별자",
  payload: "값"
}

3-2. Action Creator

Action Creator란, Action을 생성해주는 함수이며 그게 전부입니다.

function AddTodo(){
  return {
    type: "식별자",
    payload: "값"
  }
}

3-3. Dispatch

Dispatch란, Component와 Store를 감시하며 값을 전달하는 역할을 합니다.
Component에서 Action이 발행되면, 감시하고 있던 Dispatch가 Action을 Reducer로 전달합니다.
Store에서 값이 변경되면, 감시하고 있던 Dispatch가 new State를 Component로 전달합니다.

3-4. Reducer

Reducer란, 각 Action에 맞추어 어떻게 상태를 변화시킬지 관리하는 함수입니다.
Dispatch를 통해 전달된 Action과 기존 Store에 저장된 old State 객체를 합쳐서 new State 객체를 생성합니다.
이 때, 생성된 new State 객체는 Store에 저장됩니다.

3-5. Store

Store란, 이 앱의 전체 상태를 저장하고 있는 저장소입니다.

0개의 댓글