[스파르타코딩클럽] 리액트 기초반 - 2주차

yyoujg·2022년 5월 21일
0

01. 라이프 사이클이란?

1) 가상돔이란?

DOM은 html 단위 하나하나를 객체로 생각하는 모델이다.
예를 들면 'div'라는 객체는 텍스트 노드, 자식 노드 등등, 하위의 어떤 값을 가지고 있다. 이런 구조를 트리 구조라고 한다. DOM이 트리구조라는 뜻이다.

  • DOM트리 중 하나가 수정될 때마다 모든 DOM을 뒤지고 수정한 것을 찾고 모두 수정한다면 필요없는 연산이 너무 많이 일어나게 된다. 그래서 등장한 것이 가상돔이다.

  • 가상돔은 메모리 상에서 돌아가는 가짜 DOM이다.

  • 가상돔의 동작 방식: 기존 DOM과 어떤 행동 후 새로 그린 DOM(가상돔에 올라감)을 비교해서 정말 바뀐 부분만 갈아끼워준다. 돔 업데이트 처리가 간결해진다.

처음 페이지에 진입했을 때나 데이터가 변했을 때 DOM을 새로 그린다.

DOM은 사이트 구조에 따라 가상돔으 ㄹ쓰는 것보다 훨씬 성능이 좋을 수 있고(빠를 수 있고), 느릴 수도 있다.

2) 라이프 사이클이란?

컴포넌트의 라이프 사이클(= 컴포넌트 생명주기)은 정말 중요한 개념이다.
컴포넌트가 렌더링을 준비하는 순간부터, 페이지에서 사라질때까지가 라이프 사이클이다.

  • 라이프 사이클 도표

  • 컴포넌트는 생성되고 수정(업데이트)되고 사라진다.

  • 생성은 처음으로 컴포넌트를 불러오는 단계이다.

  • 수정(업데이트)는 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나. 부모 컴포넌트가 렌더링할 때 업데이트 된다.
    - props가 바뀔 때
    - stage가 바뀔 때
    - 부모 컴포넌트가 업데이트 되었을 때(리렌더링했을 때)
    - 또는 강제로 업데이트 했을 경우(forceUpdate()를 통해 강제로 컴포넌트를 업데이트 할 수 있다.)

  • 제거는 페이지를 이동하거나, 사용자의 행동(삭제 버튼 클릭 등)으로 인해 컴포넌트가 화면에서 사라지는 단계이다.

02. 함수로 보는 라이프 사이클

라이프 사이클을 아는 것은 중요하지만 클래스형 컴포넌트보다 함수형 컴포넌트를 쓰는 이유는 리액트 공식 매뉴얼에서 함수형 컴포넌트를 더 권장하기 때문이다.
(리액트 16.8버전부터 등장한 React Hooks으로 라이프 사이클 함수를 대체할 수 있기 때문이다.)

3)constructor()

생성자 함수라고도 부른다. 컴포넌트가 생성되면 가장 처음 호출된다.

4)render()

컴포넌트의 모양을 정의한다. 여기에서도 state, props에 접근해서 데이터를 보여줄 수 있다.
리액트 요소를 return에 넣어 반환해주는데 render() 안에 들어갈 내용은 컴포넌트 모양에만 관여하는 것이 가장 좋다. 즉, state나, props를 건드려 데이터를 수정하려고 하면 안된다.

5)componentDidMount()

컴포넌트가 화면에 나타나는 것을 마운트(Mount)한다고 표현한다.
didMount()는 마운트가 완료되었다는 의미이다.
이 함수는 첫 번째 렌더링을 마친후에만 딱 한 번 실행된다.
컴포넌트가 리랜더링할 때는 실행되지 않는다.
보통은 이 안에서 ajax 요청, 이벤트 등록, 함수 호출 등 작업을 처리한다.
또, 이미 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 된다.

6)componentDidUpdate(preProps, prevState, snapshot)

DidMount()가 첫 렌더링 후에 호출 되는 함수라면, DidUpdate()는 리렌더링을 완료한 후 실행되는 함수이다. 이 함수에 중요한 파라미터가 2개 있는데, preProps와 prevState이다.
각각 업데이트 되기 전 props, state이다. 이전 데이터와 비교할 일이 있을 때 쓰면 된다.
DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후이기 때문에 DOM 관련 처리를 해도 된다.

7)componentWillUnmount()

삼항연산자를 사용해서 컴포넌트를 보여주거나, 없애는 것을 조건부렌더링이라고 부른다.

03. Component란?

8)Component란?

리액트는 레고, 컴포넌트는 블록이다.
웹사이트를 조각냈을 때 조각 하나하나를 컴포넌트라고 한다.
conponent는 웹 사이트의 조각이고, 우리는 이 조각을 모아서 웹사이트에 뿌려준다.

9)State와 Props

component에서 데이터를 관리하는 방법

  • state
    state는 Component가 가지고 있는 데이터이다.
    state는 한 컴포넌트에서만 사용하는 정보를 주로 넣어놓고 생성, 수정하는 데이터이다.
    생성도 수정도 해당 컴포넌트 내에서만 이루어진다.
  • Props
    Props는 Component가 부모 Component로부터 받아온 데이터이다.
    부모 컴포넌트로부터 전달 받은 데이터를 props라고 한다.
    부모 컴포넌트가 가지고 있는 데이터는 자식 컴포넌트가 추가하거나 수정할 수 없다.
    Props로 받은 데이터는 수정할 수 없다.

04. 함수형 Component

10)함수형 Component

리액트 코딩룰 : 폴더는 소문자로 시작하는 카멜케이스를 사용
JS파일, 컴포넌트 이름은 대문자로 시작하는 카멜케이스를 사용

// 리액트 패키지를 불러온다.
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;

05. 클래스형 Component

11)클래스형 Component

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;

12)Component에서 Component로 데이터 넘겨주기

  • state 값 사용하기
render() {
    console.log(this.state);
    ...
}

this 키워드는 context 객체와 연관이 있다.
함수나 클래스 안에서 사용하면 this를 쓴 위치에 있는 값을 가지고 온다고 생각하자.

  • 컴포넌트에 props 넘겨주기
render() {
    // this 키워드를 통해 state에 접근할 수 있어요.
    console.log(this.state);
  return (
  <div className="App">
    <h1>내 버킷리스트</h1>
    {/* 컴포넌트를 넣어줍니다. */}
    {/* <컴포넌트  [props 명]={넘겨줄 것(리스트, 문자열, 숫자, ...)}/> */}
    <BucketList list={this.state.list}/>
  </div>
);

}

- 컴포넌트 확인
```javascript
const BucketList = (props) => {
    
    console.log(props);

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

07. React에서 CSS 사용하기

14)CSS in React

src폴더에 style.css파일을 만들고 그안에 스타일을 정의하고 그 파일 불러다 사용한다.
class 대신 className을 준다.
APP.js에서는 import를 했는데, BucketList.js에서는 style.css를 import하지 않는 이유

  • 자식 컴포넌트는 부모 컴포넌트에 속해있기 때문이다.
  • 즉, 자식 컴포넌트는 return에 들어 있는 리액트 요소를 부모 컴포넌트에 가져다 준다.
  • 부모와 같은 스타일 파일을 쓸 때는 부모 컴포넌트에만 import하면 된다.

08. styled-components

15)styled-components 설치하기

  • 패키지 설치하기
yarn add styled-components

16)styled-components란?
컴포넌트 스타일링 기법

  • class 이름 짓기에서 해방된다
  • 컴포넌트에 스타일을 적기 때문에, 간단하고 직관적이다.
  • CSS-in-JS 라이브러리 중 하나이다.
    컴포넌트에 스타일을 직접 입히는 방식이라고 생각해도 된다.

10. Ref! 리액트에서 돔요소를 가져오려면?

19)Ref

리액트에서 어떤 인풋박스에서 텍스트를 가져오고 싶다면 리액트 요소에서 가져온다.

  • React.createRef()
import React from "react";
import logo from "./logo.svg";
// BucketList 컴포넌트를 import 해옵니다.
// import [컴포넌트 명] from [컴포넌트가 있는 파일경로];
import BucketList from "./BucketList";
import styled from "styled-components";

// 클래스형 컴포넌트는 이렇게 생겼습니다!
class App extends React.Component {
  constructor(props) {
    super(props);
    // App 컴포넌트의 state를 정의해줍니다.
    this.state = {
      list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
    };
    // ref는 이렇게 선언합니다! 
    this.text = React.createRef();
  }

  componentDidMount(){
		// 콘솔에서 확인해보자!
    console.log(this.text);
		console.log(this.text.current);
  }

  // 랜더 함수 안에 리액트 엘리먼트를 넣어줍니다!
  render() {
    
    return (
      <div className="App">
        <Container>
          <Title>내 버킷리스트</Title>
          <Line />
          {/* 컴포넌트를 넣어줍니다. */}
          {/* <컴포넌트 명 [props 명]={넘겨줄 것(리스트, 문자열, 숫자, ...)}/> */}
          <BucketList list={this.state.list} />
        </Container>

        <div>
          <input type="text" ref={this.text}/>
        </div>
      </div>
    );
  }
}

const Container = styled.div`
  max-width: 350px;
  min-height: 80vh;
  background-color: #fff;
  padding: 16px;
  margin: 20px auto;
  border-radius: 5px;
  border: 1px solid #ddd;
`;

const Title = styled.h1`
  color: slateblue;
  text-align: center;
`;

const Line = styled.hr`
  margin: 16px 0px;
  border: 1px dotted #ddd;
`;

export default App;
  • React.useRef()
    useRef()는 리액트 훅 중 하나이다.
import React from "react";
import styled from "styled-components";

const BucketList = ({ list }) => {
  const my_lists = list;
  const my_wrap = React.useRef(null);

  console.log(my_wrap); // 콘솔로 확인해봐요!

  window.setTimeout(() => { // 1초 뒤에는?!
    console.log(my_wrap);
  }, 1000);
  return (
    <div ref={my_wrap}>
      {my_lists.map((list, index) => {
        return <ItemStyle key={index}>{list}</ItemStyle>;
      })}
    </div>
  );
};

const ItemStyle = styled.div`
  padding: 16px;
  margin: 8px;
  background-color: aliceblue;
`;

export default BucketList;

11. 클래스형 컴포넌트에서 State 관리

20)단방향 데이터 흐름이란?
데이터는 위에서 아래로, 부모에서 자식으로 넘겨줘야 한다는 소리이다.

(1)단방향으로 써야하는 이유

  • 라이프 사이클과 함께 생각해보기
    부모 컴포넌트의 state가 업데이트 되면 자식 컴포넌트도 리렌더링이 일어난다.
    만약 자식 컴포넌트의 state가 바뀐 것을 부모 컴포넌트가 props로 받는다면 자식 컴포넌트가 업데이트 될 때 부모 컴포넌트도 업데이트되고 또 자식 컴포넌트가 리렌더링 된다.

21)클래스형 컴포넌트에서 state관리 - setState()

클래스형 컴포넌트의 state를 업데이트할 때 사용하는 함수
(1)새 CRA 만들기

yarn create react-app nemo

(2)App.js를 class형 컴포넌트로 바꾼다.
(3)Array.from

12. 함수형 컴포넌트에서 State 관리

22) 함수형 컴포넌트에서 state 관리 - useState()

함수형 컴포넌트는 클래스형처럼 자체적으로 state를 가지고 있지 않지만, react hooks를 사용하면 state를 가질 수 있다.
컴포넌트를 만들고 state를 쓰는 순서(뷰 먼저 만든 다음 state를 만들고(기본값도 잡아주기) 그 다음 state를 조작하는 무언가를 만들어서 연결한다.)

profile
멋쟁이 개발자가 될거야!!

0개의 댓글