React 특강 -2

이지예·2023년 1월 17일
0

React

목록 보기
5/5

리액트가 렌더링 하게 하기 위해서는 컨테이너 안에서 병합을 해 줘야 한다.

병합하기 위한 형태이다.

<React.StrictMode>
	<headlineElement />
	<catchphriseElement />
</React.StrictMode>

마크업을 하려면 <React.StrictMode>를 만들어야 되고, 랑 를 자식으로 구성해야 된다.

컴포넌트를 쓴다는건 어떻게 쓰는것일까?

const strictMode = React.createElement(
	React.strictMode, /*클래스*/
	null, /*props는 없다.*/
	headlineElement, /*여기부터는 children*/
	catchphriseElement
) /*strictMode는 생성된 객체이다.*/

실제 DOM에 렌더링하려면 어떻게 해야 될까?

이전에 만들었던 container변수에 렌더링 하기 위해서는 ReactDOM의 api를 사용한다.

v17까지는 기존의 api인데, v18부터는 vue랑 유사한 api가 되었다.

vue는 앱을 생성한 다음, 실제 문서에 존재하는 컨테이너 노드에 마운트한다.

const {createApp} = Vue

createApp(
	data() {
		return {
			message:'Hello Vue!'
		}
	}
}).mount('#app')

이런식으로 앱을 생성. 리액트랑 반대

React는 ReactDom이 root를 생성한다.(createRoot)( React 앱은 strictMode이런 애다.)그 후에 앱을 렌더링 하는 방식이다.

React 18버전부터는 client랑 server가 분리된다. client 함 보자. createRoot api를 쓸 수 있다.

//형태
//createRoot(container[,options]);
//container는 실제 문서에 존재하는 React application의 뿌리
const reactDomRoot = ReactDOM.createRoot(container);
//options는 서버사이드 렌더링 할 때, 서버측이랑 클라이언트 측에서 동일한 형태의 아이디를 가져야 되는데, 그때 쓴다.

근데 지금 ReactDOM 참조 에러남

리액트랑 동일한 버전으로 ReactDOM도 사용해야됨

<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom@18.development.js"></script>
//react@18아니면 @18빼고 그냥 react-dom만 쓰셈

Vue는 하나의 cdn을 가지지만, React는 웹, 모바일, 데스크탑 세 가지로 분류해서 관리할 수 있기 때문에 cdn 두 개가 사용된다.

ReactDOMRoot 객체가 만들어진다.

왜 대문자가 생성한 변수랑 다르지??왜 reactDomRoot가 아니지?

prototype을 보면 render메소드, unmount메소드가 나온다. render메소드에는 children을 넣을 수 있는데, 자식들이 react의 application이다.

reactDomRoot.render(strictMode);

reactDomRoot에 render메소드 쓸 수 있으니까, react의 application역할을 하는 strictMode라는 인스턴스를 넣을 수 있다.

하드코딩해서 html구조를 직접 짜넣은 것 처럼 Elements패널에서 코드를 확인 할 수 있다.

React의 element생성, React의 하는 일, ReactDOM의 하는 일에 대해 알아봤다.


이 경고는 뭘까?

Vue의 v-for라는 directive 내에서 key같은 역할이다.

React에서는 requenceration이라는 재조정 알고리즘이 존재한다.

기존에 먼저 렌더링 됐던 리스트가 있다면, 새롭게 그려지는 가상돔의 현재 리스트랑 비교해야 된다. 비교할 때 성능적인 문제가 주어질 수 있기 때문에, 성능을 저하시키지 않기 위해 key라는 property가 매우 중요하다.

React는 에러가 아니라 경고를 하고 있다. 렌더링이 안되는 것이 아니라 업데이트가 발생했을 때 성능저하가 발생할 수 있기 때문에 리스트 안에 있는 각각의 자식들에게 고유한 key라는 property를 설정 해주면 좋다는 경고를 하고 있다.

어떻게 해결 가능한가?

at p라는 부분을 보면 우리가 작성한 부분에 대해서는 catchphriseElement이다.

catchphriseElement를 보면 하나 이상의 자식을 가지고 있다. 이 경우 데이터 타입을 보면, js의 string type과 ReactElement타입이 공존한다. ReactElement에 키가 필요하다.

abbrebiationElement로 가서 새로운 property를 설정 해 주자.

property이름은 key이고, key의 값은 고유한 이름값을 가져야 한다.

그러면 더이상 경고창이 생기지 않는다.

이처럼 기술적으로 발생할 수 있는 문제에 대해 알려주는데, 개발상에서 개발자의 경험을 향상시키기 위해 알려주는것이다.

개발용 코드를 배포용 코드로 변경 후 실행 해 보자.

//<script src="https://unpkg.com/react/umd/react.development.js" crossorigin></script>
//<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react/umd/react.production.min.js" crossorigin></script>
<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>

페이지 렌더링 해보면 더이상 경고하지 않는다.

서비스 하는데는 개발용 아니고 배포용 필요한데, 개발자에게 제공되던 안내내용이 더이상 필요없기 때문에 걷어내진다. 이는 성능 최적화와 관련된 부분이다.

그러니까 개발자는 development로 확인하는것이 문제유발 가능성 있는 부분 빠르게 확인 가능.


강의 1일차 2

React 엘리먼트 vs React 컴포넌트 / 함수의 arguments vs React의 Props

이전시간 코드들은 깃허브에서 볼 수 있음.

이전 강의에서 React api랑 ReactDOM의 API 차이 살펴봤음.기억하기

React Component

Vue는 Vue 의 element를 생성하는 객체 설정. 근데 React는 component 사용

2018년까지의 분류

  1. class Component(stateful - 상태를 가진 : container라고 부름)

  2. functional Component(stateless - 상태가 없는 : 표현을 목적으로 하고, 재사용성이 높은 component이기 때문에 presentation이라고 부름)

    함수를 사용하는데 화살표 함수를 많이들 쓴다.

2019년부터 1의 사용량이 줄고, 대부분 2로 처리하게 됨. Vue가 React보다 잠깐 사용량이 늘어서. 2019년부터 React의 Hooks API가 등장하고 나서부터 React가 다시 사용량 1위 됨.

Hooks는 Vue와 React에서 언급되는게 다름.

Vue의 Lifecycle Hooks는 React에서 class component의 Lifecycle Methods임.

React의 Hooks api는 Vue의 Composables와 같다고 볼 수 있음.

React Component의 역할은 React 요소 생성

그런데 우리는 요소를 만들었는데 왜 이걸 다시 Component로 만들어야 하는가? 재사용때문

Component를 만들고 사용하는 이유는 React요소를 재사용하기 위함.

이전에 만들었던 코드들 index.html에서 main.js로 옮기고 다시 보자.

element에서 component로 만들어보는과정?

React에서는 함수가 component역할을 사용하게 되고, 함수가 받는것이 React의 element이므로, component의 이름은 PascalCase로 해야 한다. HTML element랑 구분지어야 하기 때문에.

이제 component니까 이름에서 element를 지워야 한다.

const Headline = (props /*{}*/) => React.createElement(
	'h1',
	{className : 'headline'},
	'React 라이브러리 활용하기'
);

다른 element들도 PascalCase로 이름 바꿔주고, element도 지워주자.

arrow function 사용해서 함수화 해주자.

props라고 하는 object를 받는다.

얘는 어떻게 바꿔줄거냐면

const App = () =>
	React.createElement(
		React.StrictMode,
		null,
		React.createElement(Headline),
		React.createElement(Catchphrise)
	);

앱이라는 component로 만들어보자.

얘는 두개의 자식을 가지고, React.StrictMode라는 컴포넌트로 감싸졌다.

얘도 필요하면 props받을 수 있다.

이제는 생성된 React element를 자식으로 설정해주자.

//위에 두 줄 있고,
reactDomRoot.render(React.createElement(App));

얘는 어떻게 해야되냐면

props 객체 뒤에 각각의 자식을 넣어준다.

App코드 변경 해보자.

왜 이렇게 바꾸지?

const App = () =>
	React.createElement(
		React.Fragment, 
		null,
		React.createElement(Headline),
		React.createElement(Catchphrise)
	);

React에 Fragment를 감싸서 변환시켜보자.

//위에 두 줄 있고,
//reactDomRoot.render(React.createElement(App));
/*React.StrictMode에서 React.Fragment로 변경해보자*/
reactDomRoot.render(
	React.createElement(
		React.StrictMode,
		null,
		React.createElement(App)
	)
);

props는 없고, App이라는 컴포넌트를 렌더링해보자.

여기서 컴포넌트를 만들었기 때문에

React의 dev tool 다운해보자

React Developer Tools 크롬 앱 설치

그러면 f12누르면 component탭이 생김

그러면 app기준으로 컴포넌트 트리 생기는거 볼 수 있음.

리액트 api(컴포넌트, element)를 사용해서 재사용성이 높아질 수 있다.

우리가 createElement복붙해서 붙이면 같은 코드가 겁나 많이 반복될 수 있는거다. 그런의미로 재사용성이 높아진다.

그리고 props를 외부에서 전달받는 구조로 작성할 수 있다. props는 객체라서, 외부에서 className이라고 전달받게 되면,

‘headline’부분에 className을 기본설정 하거나, 병합 할 수 있다.

예를 들어보자

여기서 headline 컴포넌트를 사용하는 곳에 point 클래스를 부여하고 싶다고 하자.

컴포넌트 외부에서 props를 전달하고 싶을 때,

이런식으로 props를 전달하면 크롬 - f12 component 트리에서 headline 컴포넌트 보면,

props 객체에 point가 className으로 들어온다. 근데 실제 dom(Elements탭)에는 반영 안됐다.

이걸 반영해주려면 className을 안쪽에서 합성할 수 있어야 한다.

props가 className이라는 property를 가지고 있으니까,

이런식으로 병합 해 줘야 한다.

css의 클래스는 공백으로 구분 돼야 되기 때문에 저 사이에 ‘ ‘을 더해준다.

근데 이제 template litter??라는걸 사용할 수 있어서,

데이터 바인딩 가능.

이러면 컴포넌트 외부에서 얼마든지 사용자가 정의하는 커스텀 클래스 값이 반영되는 구조로 컴포넌트를 확장시키고, 재사용성을 높일 수 있다.

그럼 외부에 드러나는거(’React 라이브러리 활용하기’는 어떻게 처리하나?

얘는 props element에 children이라는 property가 들어오게 돼 있음.

좀 잘리긴 했는데 이런식으로 children 넣어줄 수 있음.

React는 슬롯 안쓰고 children 씀.

children은 하나 이상 들어올 수 있음.

이런식으로.

그러면

이렇게 배열로 들어오게 된다.

실제 ui에는 반영이 되지 않는다. (화면에 글자 안보임)

렌더링하는 과정에서 활용되지 않았기 때문.

이렇게 적어주면 화면에 드러남.

createElement api 사용 방식, props를 통해 데이터 바인딩 하는 방법, 실제 ui렌더링 되는 과정을 확인했음

컴포넌트는 재사용을 위해서 class, 함수 사용

이거로 react 요소 생성.

그러므로 element를 생성하는게 component이고, component가 반환하는 element가 ReactDOM에 의해 해석된 이후 실제 ui에 렌더링 된다.

React가 만들어내는것은 객체의 트리구조(가상돔).가상돔을 읽어와서 실제돔으로 렌더링해주는게 ReactDOM이 하는 일.

React와 ReactDOM은 역할이 구분 돼 있다.

React 상태관리

현재 element는 React strictmode안에 첫번재 자식으로 app이 들어가있고,

app안에는 자식 두개가 있다.

세번째 자식 만들어보자.

매번 createElement 만드는게 번거로우니까 Vue에서 h 함수 쓴거처럼 React의 구조분해할당 써보자.

0개의 댓글