React (3)

이선민·2021년 6월 28일
0

라이프 사이클

가상돔 DOM

html 단위 하나하나를 객체로 생각하는 모델 
DOM → 트리구조
가상돔 → 메모리 상에서 돌아가는 가짜 DOM

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

어떤 행동을 해야 DOM을 새로 그릴까?
→ 처음 페이지 진입했을 때(렌더링), 데이터가 변했을 때(리렌더링)

라이프 사이클

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

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

컴포넌트 - 생성 → 수정(업데이트) → 사라진다.
생성 → 처음으로 컴포넌트를 불러오는 단계

수정(업데이트) 
→ 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나, 
부모 컴포넌트가 렌더링 할 때 업데이트 된다.
ex) props가 바뀔 때, state가 바뀔 때, 부모 컴포넌트가 업데이트 되었을 때(=리렌더링)
강제로 업데이트 했을 경우

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

알아두면 좋은 라이프 사이클 함수

라이프 사이클 함수는 클래스형 컴포넌트에서만 사용할 수 있다.

리액트 공식 메뉴얼에서는 함수형 컴포넌트를 더 권장한다.
(리액트 16.8버전부터 등장한 React Hooks으로 라이프 사이클 함수를 대체할 수 있다.)

더 많은 라이프 사이클 함수는 아래 공식 문서에서 확인할 수 있다.

https://ko.reactjs.org/docs/react-component.html

Ref

클래스형 컴포넌트에서 React 요소를 가지고 오는 방법
→ 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;

State 관리(1)

단방향 데이터 흐름

데이터는 위에서 아래로, 부모에서 자식으로 넘겨줘야 한다!!

단방향을 써야하는 이유?
- 라이프 사이클과 함께 생각해보기!
부모 컴포넌트의 state가 업데이트 되면 자식 컴포넌트도 리렌더링이 일어난다.
만약 자식 컴포넌트 state가 바뀐 걸 부모 컴포넌트가 props로 받는다고 생각하면
자식 컴포넌트가 업데이트 될 때 부모 컴포넌트도 업데이트 된다.
그럼 또 자식 컴포넌트가 리렌더링 된다.

클래스형 컴포넌트에서 state 관리

setState() → 클래스형 컴포넌트의 state를 업데이트할 때 사용하는 함수

State 관리(2)

함수형 컴포넌트에서 state 관리

useState()

함수형 컴포넌트는 state가 없다
→ 하지만 react hooks를 사용하면 state를 가질 수 있다!

1. 새 컴포넌트를 만들기
2. App에서 컴포넌트 불러오기
3. useState()로  ex) count를 state로 등록
→ count에는 state 값이, setCount는 count라는 state 값을 수정하는 함수
4. 뷰를 만든다(=반환할 리액트 요소 만들기)
5. 함수 만들기
6. 연결하기

state를 관리하고, 함수형 컴포넌트와 클래스형 컴포넌트를 만드는 순서는 중요하다.

Evevt Listener

이벤트 리스너란 ?
→ 사용자가 어떤 행동(=이벤트)을 하는 지 아닌 지 지켜보다가 알려주는 것
대표적으로 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등이 자주 쓰인다.

https://developer.mozilla.org/ko/docs/Web/Events

클래스형 컴포넌트에서 event listener 구독하기 순서
( 이벤트 리스너는 componentDidMount()에 넣어준다)
1. ref 잡기
2. addEventListener()를 이용해서 이벤트를 등록한다.
3. 이벤트는 꼭 컴포넌트가 사라지면 지워준다.
// (1)
constructor(props) {
    super(props);

    this.state = {
      count: 3, // 숫자넣기!
    };

    // div에 ref를 먼저 잡아줍시다.
    this.div = React.createRef();
  }


// (2)
	hoverEvent = (e) => {
    // 콘솔로 이 이벤트가 누구에게서 일어났는 지 확인할 수 있습니다.
    console.log(e.target);

    if(e.target.className === 'app'){
      // 이벤트의 장본인의 배경 색을 바꿔볼까요?
      e.target.style.background = "#eee";
    }
  }

  componentDidMount() {
    // 리액트 요소가 잘 잡혔나 확인해봅시다!
    console.log(this.div);

    // 마우스를 올렸을 때, 이벤트가 일어나는 지 확인해봅시다.
    this.div.current.addEventListener("mouseover", this.hoverEvent);
  }


// (3)
componentWillUnmount() {
    // 컴포넌트가 사라질 때 이벤트를 지워줍니다.
    this.div.current.removeEventListener("mouseover", this.hoverEvent);
  }

0개의 댓글