TIL: 2022-05-21 React 입문

김하연·2022년 5월 21일
0

TIL: Today I Leaned

목록 보기
13/25

React 1주차 수업 내용 정리


가상DOM

가상돔은 메모리 상에서 돌아가는 가짜 DOM 이다.
DOM 트리 중 하나가 수정될 때마다 모든 DOM을 뒤지고, 수정할 걸 찾고, 싹 수정을 한다면? 필요없는 연산이 너무 많이 일어나기 때문에 등장한 게 가상돔이다.

  • 가상돔의 동작 방식
    기존 DOM과 어떤 행동 후 새로 그린 DOM(가상 돔에 올라갔다고 표현)을 비교해서 정
    말 바뀐 부분만 갈아끼우는 간결한 과정을 거친다.
  • 실제 돔이 그려지는 기준
  • 처음 페이지 진입했을 때
  • 데이터가 변했을 때
  • DOM이 항상 가상DOM 보다 느릴까?
    반은 맞고 반은 틀리다. DOM은 사이트 구조에 따라 가상돔을 쓰는 것보다 훨씬 성능이 빠를
    수 있고, 속이 터지게 느릴 수 있다. 가상돔은 무언가를 계속 업데이트 하고 만드는 연산이 들어가기 때문에 사이트 구조가 복잡할 경우 즉, 사이트 구조에 따라 달라질 수 있다.

라이프사이클

컴포넌트가 렌더링을 준비하는 순간부터, 페이지에서 사라질 때까지를 라이프 사이클이라고 한다.

  • 컴포넌트는 생성되고 > 수정(업데이트)되고 > 사라진다.
  • 생성은 처음으로 컴포넌트를 불러오는 단계 = 마운트
  • 수정(업데이트)는 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나, 부모 컴포넌트가 렌더링할 때 업데이트 된다.
    • props가 바뀔 때
    • state가 바뀔 때
    • 부모 컴포넌트가 업데이트 되었을 때(=리렌더링했을 때)
    • 또는, 강제로 업데이트 했을 경우. (forceUpdate()를 통해 강제로 컴포넌트를 업데이트할 수 있다.)
  • 제거는 페이지를 이동하거나, 사용자의 행동(삭제 버튼 클릭 등)으로 인해 컴포넌트가 화면에서 사라지는 단계

Component

리액트가 레고라면, 컴포넌트는 블럭.
화면을 이루는 구조들의 조각 조각이라고 볼 수 있다.

  • State와 Props
    state는 한 컴포넌트에서만 사용하는 정보를 주로 넣어놓고 생성, 수정하는 데이터
    props는 부모로부터 가져온 데이터.
    하위 컴포넌트에서는 props를 바꿀 수 없고 state만 바꿀 수 있다.

  • Class형 컴포넌트
    현재 리액트에서는 함수형 컴포넌트만 쓰도록 권장하고 있지만, 이미 만들어진 사이트들이 Class형으로 제작되었을 수도 있기 때문에 Class형에 대한 어느정도의 이해가 있으면 좋다. 아래가 Class형 컴포넌트의 기본 구조이자 필수 요소.

class LifecycleEx extends React.Component {
	// 생성자 함수
	constructor(props) { // props: 부모로부터 받아온 데이터
		super(props); // 부모로부터 받아온 데이터 불러오기

		this.state = { // state: 이 컴포넌트에서 사용하고 제어하는 요소
			cat_name: "나비",
		};

		console.log("in constructor!");
	}
  	// 랜더 함수 안에 리액트 엘리먼트를 넣어준다
	render() {
		console.log("in render!");

		return (
			<div>
				{/* render 안에서 컴포넌트의 데이터 state를 참조할 수 있다. */}
				<h1>제 고양이 이름은 {this.state.cat_name}입니다.</h1>
				<button onClick={this.changeCatName}>고양이 이름 바꾸기</button>
			</div>
		);
	}
 }

아래는 Class형 컴포넌트에서 추가로 조작 가능한 요소들

constructor(){} // 초기화하는 생성자 함수
render() // 렌더링, 바꿀 요소가 return에 있고 그 내용이 가상DOM 통해서 진짜 DOM으로 올라간다. 
componentDidMount() { // 마운트(첫 번째 렌더링) 끝난 후 호출
	console.log("in componentDidMount!");
}
componentDidUpdate(prevProps, prevState) { // 리렌더링이 끝난 후 호출, 가상 DOM이 실제 DOM에 올라간 상태
  	console.log(prevProps, prevState); 
  	// prevProps: 부모한테 받아온 것, PrevState: 내가 갖고 있는 것
  	// 업데이트 되기 전 내용
	console.log("in componentDidUpdate!");
}
componentWillUnmount() { // 컴포넌트가 화면에서 사라지기 직전에 호출
  console.log("in componentWillUnmount!");
}
  • 함수형 컴포넌트
// function Bucketlist(props){ 함수 선언식으로 사용해도 상관 없음

// }

const Bucketlist = (props) => { // props: 부모한테서 받아온 데이터
  return null; // DOM으로 올라갈 요소들
}
  • import, export의 두가지 방법
import BucketList from './BucketList';
export {BucketList};

import {BucketList} from "./BucketList";
export default BucketList;

Styled Components

컴포넌트에 스타일을 직접 입히는 방식이라서 직관적이고 간단하다.

// 설치하기
yarn add styled-components

package.json > dependencies 안에 설치한 패키지들이 다 저장되어있음.
프로젝트 안에서 package를 설치할 때는 해당 프로젝트 폴더 안에서 설치해야함.

${(props)=>{
    return props.bg_color;
}}

${(props)=>(props.bg_color)}; // 위 코드의 축약형. return 작성할 필요 없음

Styled-components에서는 SCSS도 사용 가능. nesting도 가능하다.


React 에서 돔 요소 가져오는 방법

document.getElementById() 처럼 자바스크립트에서 요소를 가져오는 방법은 진짜 DOM에 생성된 요소를 가져오는 것이다. 리액트에서는 가상 DOM에 먼저 요소를 추가하고 가상 DOM이 진짜 DOM에 추가되는 방식이기 때문에 리액트 요소를 가져오기 위해 다른 방법을 쓴다.

  1. React.createRef() > Class형 컴포넌트에 사용
class App extends React.Component{
  constructor(props){
    super(props);

    this.state = {
      list: ['호주 케언즈 가기', '스카이다이빙', '남미여행'],
    }

    this.text = React.createRef();
  }

  componentDidMount(){
    console.log(this.text);

  }

  render() {
    console.log(this.text.current)
    return (
      <div className="App">
        <Container>
          <BucketWrap>
            <h1>버킷리스트</h1>
            <BucketList list={this.state.list}/>
          </BucketWrap>
        </Container>

        <div>
          <input tpye="text" ref={this.text} 
          onChange={()=>{
            console.log(this.text.current.value)
          }}/>
        </div>
      </div>
    )
  }
}

1.React.useRef(초기값) > 함수형 컴포넌트에서 사용

const BucketList = ({list}) => {
	const my_lists = list;
    const my_ul = React.useRef(null); // nuill:초기화 해줄 값			
    
    onsole.log(my_ul);
    window.setTimeout(()=>{console.log(my_ul)}, 1000);
	return (
		<ul ref={my_ul}>
        	my_lists.map((list, index) => {
					console.log(list);
					return <Items key={index}>{list}</Items>;
				})
			}
		</ul>
	);
};

State 관리

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

  • 부모가 자식에게 데이터를 넘겨줄 경우
    부모의 state를 자식에게 넘겨줄 경우, props가 되고 부모의 state가 변할 경우 부모는 re-rendering이 되고 자식도 re-rendering이 된다.

  • 자식이 부모에게 데이터를 넘겨줄 경우
    자식이 부모에게 넘겨주는 데이터는 state혹은 흔치 않게 props가 있는데, 자식이 부모의 state나 props에 영향을 주었으니 부모가 re-rendering이 된다. 그럴 경우 부모가 re-rending되었기 때문에 자식도 re-rendering 되고 게속해서 무한 반복이 된다.
    부모의 props나 state를 자식에게 넘겨주지 않을 경우는 무한 반복에 빠지지는 않는다. (ex: 자식 요소에서 무언가를 클릭해야 부모의 데이터가 바뀔 경우, 다시 버튼을 클릭하지 않으면 무한루프에 빠지지는 않게된다.) 그러나 이럴 경우 데이터 트리가 깔끔하진 않으므로 양방향보다는 단방향 데이터 흐름을 사용하는 것이 더 좋다.


음.. 오늘 리액트 강의 처음으로 들었는데, 너무 헷갈리는 것 같다.
컴포넌트를 Class타입이랑 함수 타입을 동시에 알려줘서 더 헷갈리는 것 같기도 하고, 미묘하게 쓰이는 방식이 다르니까 좀 더 혼란스럽긴 하다 ㅜㅜ
이제 리액트에서 함수형 컴포넌트만 쓰라고 권고를 했다고 하는데, 실무에 투입됐을 때 이전에 만들어진 사이트들이 Class타입으로 제작되었을 수도 있으니 보는 눈을 키우기 위해 배우는건 필요하긴 한 것 같다. 계속 하다보면 익숙해지겠지..?!!!?!?!?!
vue 보다 react가 더 직관적이라고..? 그런 말을 들은 것 같은데 나는 vuer가 더 쉬운 것 같은 그런 느낌...?

0개의 댓글