TIL 20211003 [항해99 18일차]

Arong·2021년 10월 3일
  • 함수형 컴포넌트
// 리액트 패키지를 불러옵니다.
import React from 'react'; 

// 함수형 컴포넌트는 이렇게 쓸 수도 있고
// function Bucketlist(props){
//     return (
//         <div>버킷 리스트</div>
//     );
// }

// 이렇게 쓸 수도 있어요. =>가 들어간 함수를 화살표 함수라고 불러요.
// 저희는 앞으로 화살표 함수를 사용할거예요.
// 앗 () 안에 props! 부모 컴포넌트에게 받아온 데이터입니다.
// js 함수가 값을 받아오는 것과 똑같이 받아오네요.
const BucketList = (props) => {

    // 컴포넌트가 뿌려줄 ui 요소(리엑트 엘리먼트라고 불러요.)를 반환해줍니다.
    return (
        <div>
            버킷 리스트
        </div>
    );
}

// 우리가 만든 함수형 컴포넌트를 export 해줍니다.
// export 해주면 다른 컴포넌트에서 BucketList 컴포넌트를 불러다 쓸 수 있어요.
export default BucketList;

App.js로 돌아가서 BucketList 컴포넌트를 불러오기.

import React from 'react';
import logo from './logo.svg';
import './App.css';
// BucketList 컴포넌트를 import 해옵니다.
// import [컴포넌트 명] from [컴포넌트가 있는 파일경로];
import BucketList from './BucketList';

function App() {

  return (
    <div className="App">
      <h1>내 버킷리스트</h1>
      {/* 컴포넌트를 넣어줍니다. */}
      <BucketList/>
    </div>
  );
}

export default App;
  • 클래스형 컴포넌트
import React from 'react';
import logo from './logo.svg';
import './App.css';
// BucketList 컴포넌트를 import 해옵니다.
// import [컴포넌트 명] from [컴포넌트가 있는 파일경로];
import BucketList from './BucketList';

// 클래스형 컴포넌트는 이렇게 생겼습니다!
class App extends React.Component {

  constructor(props){
    super(props);
    // App 컴포넌트의 state를 정의해줍니다.
    this.state = {
      list: ['영화관 가기', '매일 책읽기', '수영 배우기'],
    };
  }

  // 랜더 함수 안에 리액트 엘리먼트를 넣어줍니다!
  render() {
      return (
      <div className="App">
        <h1>내 버킷리스트</h1>
        {/* 컴포넌트를 넣어줍니다. */}
        <BucketList/>
      </div>
    );
  }
}

export default App;

p.s. 라이프 사이클 함수는 클래스형 컴포넌트에서만 사용할 수 있다.
리액트 16.8버전부터 등장한 React Hooks으로 라이프 사이클 함수를 대체할 수 있다.😉

  • 라이프 사이클 함수로 보는 라이프 사이클
  • constructor()
    생성자 함수라고도 부르며, 컴포넌트가 생성되면 가장 처음 호출되는 친구다.
  • render()
    컴포넌트의 모양을 정의하는 친구!
    여기에서도 state, props에 접근해서 데이터를 보여줄 수 있다.
    리액트 요소를 return에 넣어 반환해주며, render() 안에 들어갈 내용은 컴포넌트의 모양에만 관여하는 것이 가장 좋다.
    즉, state나, props를 건드려 데이터를 수정하려고 하면 안된다!
  • componentDidMount()
    컴포넌트가 화면에 나타나는 것을 마운트(Mount)한다고 표현한다. didMount()는 마운트가 완료 되었다는 소리다. 이 함수는 첫번째 렌더링을 마친 후에만 딱 한 번 실행된다. 컴포넌트가 리렌더링할 때는 실행되지 않는다. 보통은 이 안에서 ajax 요청, 이벤트 등록, 함수 호출 등 작업을 처리한다. 또, 이미 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 된다!
  • componentDidUpdate(prevProps, prevState, snapshot)
    DidMount()가 첫 렌더링 후에 호출 되는 함수라면, DidUpdate()는 리렌더링을 완료한 후 실행되는 함수이다. 이 함수에 중요한 파라미터가 2개 있는데, prevProps와 prevState이다. 각각 업데이트 되기 전 props, state이다. 이전 데이터와 비교할 일이 있다면 가져다 쓰도록 하자.
    DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 된다!
  • componentWillUnmount()
    컴포넌트가 DOM에서 제거 될 때 실행하는 함수이다.
    만약 우리가 스크롤 위치를 추적 중이거나, 어떤 이벤트 리스너를 등록했다면 여기에서 꼭꼭 해제를 해줘야 한다. 컴포넌트 없이 이벤트만 남겨둘 순 없기때문이다.
  • Hook이란?

Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“할 수 있게 해주는 함수이다. Hook은 class 안에서는 동작하지 않는다. 대신 class 없이 React를 사용할 수 있게 해주는 것이다.
React는 useState 같은 내장 Hook을 몇 가지 제공한다. 컴포넌트 간에 상태 관련 로직을 재사용하기 위해 Hook을 직접 만드는 것도 가능하다.

  • State Hook

Hook을 호출해 함수 컴포넌트(function component) 안에 state를 추가했다. 이 state는 컴포넌트가 다시 렌더링 되어도 그대로 유지될 것이다. useState는 현재의 state 값과 이 값을 업데이트하는 함수를 쌍으로 제공한다. 우리는 이 함수를 이벤트 핸들러나 다른 곳에서 호출할 수 있다. 이것은 class의 this.setState와 거의 유사하지만, 이전 state와 새로운 state를 합치지 않는다는 차이점이 있다.

useState는 인자로 초기 state 값을 하나 받는다. 카운터는 0부터 시작하기 때문에 위 예시에서는 초기값으로 0을 넣어준 것이다. this.state와는 달리 useState Hook의 state는 객체일 필요가 없다. 물론 원한다면 그렇게도 가능... 이 초기값은 첫 번째 렌더링에만 딱 한번 사용된다.

  • 여러 state 변수 선언하기

하나의 컴포넌트 내에서 State Hook을 여러 개 사용할 수도 있다.
배열 구조 분해(destructuring) 문법은 useState로 호출된 state 변수들을 다른 변수명으로 할당할 수 있게 해준다. 이 변수명은 useState API와 관련이 없다. 대신에 React는 매번 렌더링할 때 useState가 사용된 순서대로 실행할 것이다.

  • Effect Hook

React 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업을 “side effects”(또는 짧게 “effects”)라고 한다. 왜냐하면 이건 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이기 때문이다.

Effect Hook, 즉 useEffect는 함수 컴포넌트 내에서 이런 side effects를 수행할 수 있게 해준다. React class의 componentDidMount 나 componentDidUpdate, componentWillUnmount와 같은 목적으로 제공되지만, 하나의 API로 통합된 것이다.

useState와 마찬가지로 컴포넌트 내에서 여러 개의 effect를 사용할 수 있다.

  • Hook 사용 규칙

Hook은 그냥 JavaScript 함수이지만, 두 가지 규칙을 준수해야 한다.
1) 최상위(at the top level)에서만 Hook을 호출해야 한다. 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하지 않기! 대신 early return이 실행되기 전에 항상 React 함수의 최상위(at the top level)에서 Hook을 호출해야 한다. 이 규칙을 따르면 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장된다. 이러한 점은 React가 useState 와 useEffect 가 여러 번 호출되는 중에도 Hook의 상태를 올바르게 유지할 수 있도록 해준다.
2) React 함수 컴포넌트 내에서만 Hook을 호출해야 한다. 일반 JavaScript 함수에서는 Hook을 호출해서는 안 된다. (Hook을 호출할 수 있는 곳이 딱 한 군데 더 있다. 바로 직접 작성한 custom Hook 안이다.)
이 규칙들을 강제하기 위해서 linter plugin을 제공하고 있다.


오늘은 그동안 과제하면서 일단 잘 몰라도 그냥 사용했었던 라이프사이클과 클래스형 컴포넌트, 함수형 컴포넌트, 훅에 대해 공부했다. 라이프사이클과 클래스형 컴포넌트는 과제때 사용하질 않아서 공부하면서 낯설었다... 함수형 컴포넌트에서 훅의 역할을 클래스형 컴포넌트에서 라이프사이클이 한다는걸 다시 복습하면서 헷갈렸던 useEffect와 useState 훅의 쓰임도 어느정도 이해하게 됐다.
리액트 심화주차 개인공부중인 지금 기본주차보다 더 열심히 공부해야하는데 어제 permit.js에서 막히면서 오늘까지 집중이 잘 안되 많이 못한거같다.. 대체 왜 Permit 컴포넌트가 적용이 안되는 것인가ㅠㅠ 정신차려서 다시 마음다잡고 열공하자...!

profile
아롱의 개발일지

0개의 댓글