Skip to main content

7 posts tagged with "React"

View All Tags

· 3 min read

리액트와 리랜더링 알아보기

바닐라 JS 변경으로 인해 Element를 다시 그린다

const rootElement = document.getElementById('root')

function random() {
const number = Math.floor(Math.random() * (10 - 1) + 1)

const element = `
<button>${number}</button>
`

rootElement.innerHTML = element
}

random()
  • 바닐라 JS에서 요소에 변경이 발생하면 모든 element들이 다시 그려지게 된다

React는 변경된 부분만 다시 그린다

const rootElement = document.getElementById('root')

function random() {
const number = Math.floor(Math.random() * (10 - 1) + 1)

const element = <button>{number}</button>

ReactDOM.render(element, rootElement)
}

random()
  • React에서는 변경된 요소들의 값만 변경이 이루어 진다

모든 요소가 변경되는 것과 특정 요소만 변경되는 것 둘은 장단점이 존재한다

리액트와 리랜더링 알아보기 2

비교 알고리즘

  • 앨리먼트 타입이 바뀌는 경우
    • 이전 앨리먼트는 버리고 새로 그린다
  • 앨리먼트 타입은 같고 props 만 변경된 경우
    • key를 먼저 비교하고, props를 비교해서 변경사항을 반영한다

정리

  • 리액트의 앨리먼트는 불변 객체이다
  • 리액트의 변경 사항 반영은 리액트에게 일임한다
  • 리액트의 비교는 Reconciliation(재조정)이다 비교 연산(알고리즘)을 통해 진행한다
    • 타입이 바뀌면 이전 내용을 버리고 다시 그림
    • 타입이 같으면 key값 비교후 변경된 props에 대한 변경사항만 반영한다
  • Virtual Dom은 리액트가 가상 돔을 가지고 있다가 비교할떄 사용한다

참조

  • 패스트 캠퍼스 온라인 강좌(한 번에 끝내는 React의 모든 것 초격자 패키지 Online)

· 6 min read

동기

  • state나 props가 갱신되면 render() 함수는 새로운 React Element Tree를 반환할 것이다
  • 이때 React는 방금 만들어진 트리에 맞게 가장 효과적으로 UI를 갱신하는 방법을 알아낼 필요가 있다
  • 하나의 트리를 가지고 다른 트리로 변환하기 위한 최소한의 연순 수를 구하는 알고리즘이 필요하다
  • 최첨단의 알고리즘도 n개의 엘리먼트가 있는 트리에 대해 O(n^3)의 복잡도를 가진다(너무 비싼 연산)
  • React는 두가지 가정을 기반하여 O(n) 복잡도의 휴리스틱 알고리즘을 구현했다
  1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다
  2. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해 줄 수 있다

비교 알고리즘(Diffing Algorithm)

  • 두 개의 트리를 비교할 때, React는 두 엘리먼트의 루트(root) 엘리먼트부터 비교한다
  • 이후의 동작은 루트 엘리먼트의 타입에 따라 달라진다

엘리먼트 타입이 다른 경우

  • 두 엘리먼트의 타입이 다르면, 이전 트리를 버리고 완전히 새로운 트리를 구축한다(새로 그린다는 의미)
  • 에를 들어 a태그에서 img로, Article에서 Comment로 Button에서 div로 바뀌는 케이스가 모두 트리 전체를 재구축 하는 경우이다
  • 트리를 버릴 때 이전 DOM 노드들은 모두 파괴된다
    • compoenentWillUnmount()가 실행된다
  • 새로운 트리가 만들어질 떄, 새로운 DOM 노드들이 DOM에 삽입된다
    • UNSAFE_componentWIllMount()가 실행된다(Depreciated)
    • compoenentDidMount()가 이어서 실행된다
    • 이전 트리와 연관된 모든 state는 사라진다
<div>
<Counter />
</div>

<span>
<Counter />
</span>
  • 엘리먼트 타입이 변경되었기 때문에 Counter는 사라지고, 새로 다시 마운트가 된다

DOM 엘리먼트 타입이 같은 경우

  • 같은 타입의 두 React DOM 엘리먼트를 비교할 때, React는 두 엘리먼트의 속성을 확인하여, 동일한 내역은 유지하고 변겨된 속성들만 갱신한다
<div className='before' title='stuff' />

<div className='after' title='struff' />
  • React는 새로운 엘리먼트의 내용을 반영하기 위해 현재 컴포넌트 인스턴스의 props를 갱신한다
  1. UNSAFE_componentWillReceiveProps
  2. UNSAFE_componentWillUpdate(Depreciated)
  3. componentDidUpdate

자식에 대한 재귀적 처리

  • DOM 노드의 자식들을 재귀적으로 처리할 때, React는 기본적으로 동시에 두 리스트를 순회하고 차이점이 있으면 변경을 생성한다
<ul>
<li>First</li>
<li>Second</li>
</ul>

<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
  • First, Second의 일치를 확인하고 Third를 생성한다
  • 비효율이 발생하는 경우
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>

<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
  • React는 Duke 와 Villanova 종속 트리를 그대로 유지하는 대신 모든 자식을 변경한다(비효율)

Keys

  • 위와 같은 순차적 비교에서 발생하는 비효율을 제거하기 위해 key 속성을 지원한다
  • React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인한다
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>

<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
  • 2014 key를 가진 엘리먼트를 추가하고, 2015, 2016 key를 가진 엘리먼트는 그저 이동만 한다
  • key를 설정할떄는 일반적으로 식별자를 key로 설정한다
<li key={item.id}>{item.name}</li>
  • key는 오로지 형제 사이(같은 속성 태그를 의미하는듯)에서만 유일하면 되고, 전역으로는 유일할 필요가 없다
  • 배열의 인덱스를 key로 사용할 수도 있지만, 재배열 하는 경우 비효율적으로 동작할 것이다
  • 인덱스를 key로 사용할 경우 state 관련 문제가 발생할 수 있다
    • 항목의 순서가 바뀔경우 key 또한 바뀌면, 그 결과로 state가 엉망이 되나가 의도치 않은 결과가 생길 수 있다

· 3 min read

엘리먼트 렌더링 React Document 정리

엘리먼트 렌더링

  • 엘리먼트는 React 앱의 가장 작은 단위이다
const element = <h1>Hello, World</h1>
  • 브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며(plain object) 쉽게 생성할 수 있다
  • ReactDOM은 React 엘리먼트와 일차하도록 DOM을 업데이트 한다

DOM에 엘리먼트 렌더링하기

  • HTML에 root div가 있다고 가정한다
<div id="root"></div>
  • 이 안에 들어가는 모든 엘리먼트를 React DOM에서 관리하기 때문에 이것을 "루트(root)" DOM노드라고 부른다
  • React로 구현된 애플리케이션은 일반적으로 하나의 루트 DOM 노드가 있다
  • React를 기존 앱에 통합하려는 경우 원하는 만큼 많은 수의 독립된 루트 DOM 노드가 있을 수 있다(이해 못함)
  • React 엘리먼트를 렌더링 하기 위해서는 우선 DOM 엘리먼트를 ReactDOM.createRoot()에 전달한다음 React 엘리먼트를 root.render()에 전달해야 한다
const rootElement = document.getElementById('root')
const element = <h1>Hello, World</h1>
ReactDOM.render(element, rootElement)

렌더링 된 엘리먼트 업데이트하기

  • React 엘리먼트를 불변객체이다
  • 엘리먼트를 생상한 이후에는 해당 엘리먼트의 자식이나 속성을 변경할 수 없다
  • 엘리먼트 영화에서 하나의 프레임과 같이 특정 시점의 UI를 보여준다
  • 위 설명을 바탕으로 하면 UI를 업데이트 하는 유일한 방법은 새로운 엘리먼틑 생성하여 이를 React로 전달하는 것이다
  • Tick Clock Example
const rootElement = document.getElementById('root')

function tick() {
const element = (
<div>
<h1>Hello, World</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
)

ReactDOM.render(element, rootElement)
}

setInterval(tick, 1000)
  • 1초 마다 tick 함수를 호출하여 엘리먼트의 변화를 화면에 보여준다

변경된 부부만 업데이트하기

  • ReactDOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교하고 DOM을 원하는 상태로 만드는데 필요한 경우에만 DOM을 업데이트한다
  • 코드 상에서는 초당 element를 모두 다시 render하지만, 실제 React는 변경된 텍스트 노드만 업데이트 한다

· 3 min read
const paint = () => (
<>
<h1>Hi</h1>
<h3>Bye</h3>
</>
)
  • 지난 시간에 만들어 변수로 할당했던 내용을 paint 라는 함수로 변경

함수를 호출하여 element 변수에 할당

const element = (
<>
{paint()}
{paint()}
{paint()}
</>
)
  • element라는 변수에 paint함수를 3번 호출하는 react 요소를 만들어 할당

선언된 element를 rootElement에 render

ReactDOM.render(element, rootElemet)

parameter를 갖는 함수로 변경

const paint = (title, description) => (
<>
<h1>{title}</h1>
<h3>{description}</h3>
</>
)

const element = (
<>
{paint("Name", "Davidyoon")}
{paint("Age", "34")}
{paint("Country", "Korea")}
</>
)
  • Custom Element를 커스텀하게 만들어 함수화 하여 필요한 곳에서 다양하게 활용할 수 있다

Custom Element 만들기

const Paint = ({title, description}) => (
<>
<h1>{title}</h1>
<h3>{description}</h3>
</>
)

const element = (
<>
<Paint title="Hello" description="hello" />
</>
)
  • 함수형 Custom Element를 생성할때는 대문자 이름을 기본으로 한다
    • 소문자로 시작할 시 Warning 과 함께 정상적인 출력이 되지 않음
  • param값을 넣어주는 곳에는 props로 {} 안에 포함되어야 한다
  • HTML 태그 처럼 내부 요소처럼 파라미터를 작성해 주면 된다

Children 넣어보기

const Paint = ({title, description, children}) => (
<>
<h1>{title}</h1>
<h3>{description}</h3>
{children}
</>
)

const element = (
<>
<Paint title="Hello!" description="it's me">
<span>Davidyoon</span>
</Paint>
</>
)

  • Custom Element에는 children을 넣을 수 있다
  • Paint 컴포넌트에 span 태그 안에 커스텀한 children을 넣어서 사용 가능하다

정리

  • Function 은 재사용이 가능한 Element 즉, Custom Element를 만드는데 사용된다
  • Custom Element를 만들 때에는 기존 html tag와 구분하여 대문자로 만들어야 한다(필수)
  • Children은 당연히 개수에 제한이 없다

참조

  • 패스트 캠퍼스 온라인 강좌(한 번에 끝내는 React의 모든 것 초격자 패키지 Online)

· 2 min read

멀티 Element 생성하기

div className="root"에 어떻게 여러개의 element를 넣으 수 있을까 ?

<div id="root">

const rootElement = document.getElementById('root')
const element = (
<div className='box' children= {[
React.createElement('h1', null, 'Hi'),
React.createElement('h3', null, 'Bye')
React.createElement('h5', null, 'Hello')
]}
)
  • children 속성에 여러개의 element를 넣을 수 있기 때문에 createElement를 사용하여 여러 개의 element를 생성할 수 있다
  • 단 위와 같이 생성할 경우 아래와 같은 형태가 된다
<div className='root'><div className='box'> </div></div>
  • 만약 root 밑에 div 태그 없이 h1, h3, h5를 생성하고 싶다면 React.Fragment를 사용한다
const element = ( <React.Fragment children={
[
React.createElement('h1', null, 'Hi'),
React.createElement('h3', null, 'Bye')
React.createElement('h5', null, 'Hello')
]
}
)
  • 위와같이 생성할 경우 아래와 같은 형태가 된다
<div className='root'><h1>Hi</h1><h3>Bye</h3> </h5>Hello</h5></div>
  • React.Fragment는 부모로써 감싸주는 역할을 한다
const element = ( <React.Fragment> {
[
<h1>Hi</h1>,
<h3>Bye</h3>,
<h5>Hello</h5>
]
}
</React.Frament>
)
  • children 속성을 제거하고 JSX 를 사용하여 위와 같이 표현할 수도 있다
const element =
<>
<h1>Hi</h1>
<h3>Bye</h3>
<h5>Hello</h5>
<>
)
  • 위와 같이 는 React.Fragment를 의미한다

참조

  • 패스트 캠퍼스 온라인 강좌(한 번에 끝내는 React의 모든 것 초격자 패키지 Online)

· 2 min read

JSX와 Babel, JSX 다루기

JXS

const element = <h1>Hello, World!</h1>

문자도 HTML도 아닌 Javascript 확장 문법

  • JSX를 사용하기 위해서는 Babel이 필요하다

Babel

JavaScript Complier 컴파일러: 언어 해석기, 특정 언어를 다른 프로그래밍 언어로 옮기는 프로그램 정확히 Babel은 Javascript 로 결과물을 만들어주는 컴파일러이다 소스 대 소스 컴파일러(Transpiler)라고 불린다 새로운 ESNext 문법을 기존의 브라우저에서 사용하기 위해서는 babel이 필수이다

  • JSX 문법을 기존 html에 작성하여 브라우저로 읽어도 원하는 동작을 하지 않는데, 이유는 바벨이 없어서 문법을 브라우저가 이해하지 못하기 때문이다

UNPKG

fast, global content delivery network for everthing on npm

React 코드를 JSX로 대체하기

<script type="text/babel">
const rootElement = document.getElementById('root')
const element = <h1 className="title">Hello World!</h1>
ReactDOM.render(element, rootElement)
</script>
  • 바벨을 적용하여 브라우저에서 JSX를 사용 가능하도록 적용

Spread 연산자

const props = {className: titleClassName, children: text}
const element = <h1 {...props} />

props로 생성된 객체를 h1 태그 안에 각각의 요로소 key value 형태로 넣어주는 연산자

const element = <h1 className={props.className} children={props.children} />

위와 같이 표현할 수도 있다

정리

JXS 는 React.createElement 표현식 Babel은 Javascript compiler JSX다루기 spread 연산자

· 4 min read

React

  • 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리
  • Virtual DOM / JSX / Flux / Functional Programming

Dom 다루기 Element 생성하기

Dom

  1. 웹 페이지는 어떻게 만들어 질까?
  • DOM(Document Object Model)은 웹 페이지에 대한 인터페이스
  • 웹 브라우저가 원본 HTML 문서를 읽어들인 후, 스타일을 입히고 대화형 페이지로 만들어 뷰 포트에 표시하기까지의 과정을 "Critical Rendering Path"라고 한다
  • 이 과정 여러 단계로 나누어져 있지만, 이 단계들을 대략 두 단계로 나눌 수 있다
  • 첫 번째 단계에서 브라우저가 읽어들인 문서를 파싱하여 최종적으로 어떤 내용을 페이지에 렌더링할지 결정
  • 두 번째 단계에서 브라우저가는 해당 렌더링을 수행
  • 첫 번쨰 과정을 걸치면 "렌더 트리"가 생성된다
  • 렌더 트리는 웹 페이지에 표시될 HTML 요소들과 이와 관련된 스타일 요소들로 구성된다
  • 브라우저는 렌더 트리를 생성하기 위해 다음과 같이 두 모델이 필요하다
    • DOM(Document Object Model) - HTML 요소들의 구조화된 표현
    • CSSOM(Cascading Style Sheets Object Model) - 요소들과 연관된 스타일 정보의 구조화된 표현

Vanilla JS

  • 순수 자바스크립트
  • 특정 라이브러리나 프레임워크를 사용하지 않은 그 자체의 자바스크립트

CodeSandBox

  • 프로트엔드 코드를 작성하고 이것저것 시도해볼 수 있는 모래상자(놀이도구)
  • React 등 다양한 환경에 대한 기본 설정이 되어있음
  • https://codesandbox.io/

CDN

  • Content Delivery Network
  • 웹에서 사용되는 다양한 컨텐츠(리소스)를 저장하여 제공하는 시스템

Element 생성하기

  1. vanilla JS
const rootElement = document.getElementById("root")
const element = document.createElement('h1')
element.textContent = "Hello, World!"
rootElement.appendChild(element)
  1. React
const rootElement = document.getElementById("root")
const element = React.createElement('h1', { children: "Hello World!"})
ReactDOM.render(element, rootElement);

참조

  • 패스트 캠퍼스 온라인 강좌(한 번에 끝내는 React의 모든 것 초격자 패키지 Online)
  • Dom은 정확히 무엇일까? https://wit.nts-corp.com/2019/02/14/5522
  • MDN
    • Mozilla Develop Network
    • 웹 표준과 모질라 프로젝트에 대한 개발 문서들이 담긴 모질라의 공식 웹 사이트