2024.02.04 TIL

Oneik·2024년 2월 4일
0
post-thumbnail

리액트란

사용자 인터페이스를 만들기 위한 JavaScript 라이브러리

  • 싱글 페이지 애플리케이션을 만들 때 사용한다
  • 바닐라 자바스크립트로도 구현할 수 있으나, 코드가 너무 길어지기 때문에 리액트를 사용한다

싱글 페이지 애플리케이션(Single Page Application)이란?

서버로부터 새로운 페이지를 가져오지 않고, 현재 페이지를 동적으로 다시 작성하는 방식

  • 페이지의 내용(HTML)만을 바꾸기 때문에, 효율적이다
  • 페이지를 새로 생성하는 과정이 없기 때문에, 새로고침 없이 부드럽게 동작한다

리액트의 장점

  • HTML함수, array, object 에 보관하고 재사용할 수 있기 때문에, 큰 프로젝트일수록 HTML 관리가 편해졌다
  • 같은 리액트 문법으로 모바일 앱개발도 가능하다(React Native)
  • Virtual DOM 을 사용함으로써, 실제 브라우저에 접근하지 않고 화면을 수정하는 것이 가능하다

리액트의 단점

  • Virtual DOM, JSX, Component, State, Props 등 다양한 개념에 대해서 배워야 하기 때문에, 학습량이 방대하다
  • VIEW 이외의 기능은 다른 라이브러리를 이용하거나 직접 구현해야한다
  • 첫 화면의 로딩 시간이 길다

동작 원리

더블 버퍼링이란, 두 개의 버퍼(메모리 영역)를 사용하여 하나에서 이미지를 준비하고 준비된 이미지를 다른 하나로 복사함으로써 화면을 갱신하는 방식

  • Virtual DOM 은 더블 버퍼링 기법과 비슷하다
  • 브라우저의 실제 화면에 직접 변경하는 것은 많은 연산이 필요하기 때문에, 더블 버퍼링 기법을 사용한다

동작 방식

React Virtual DOM Explained in Simple English - Programming with Mosh

  • 초기 렌더링
    - 가상 DOM을 변경한다(State Change)
    - 재조정한다(Compute Diff)
    - 실제 DOM을 업데이트 한다(Re-render)

JSX(Javascript Syntax eXtention)

자바스크립트의 확장 문법

  • 리액트는 JSX 문법 사용
  • XML과 유사한 형태로 리액트의 요소를 표현
  • 브라우저는 JSX를 이해하지 못하기 때문에, 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트 코드로 변환된다

리액트의 소스 구조

index.html ⟸ index.tsx ⟸ App.tsx

  • App 컴포넌트를 정의한다
  • index.tsx에서 App 컴포넌트를 가져온다
  • App 컴포넌트는 ReactDOM.render 메소드를 이용해 실제 DOM에 렌더링한다
  • App 컴포넌트가 index.html 파일의 특정 DOM 요소 안에 렌더링된다

JSX 기본 문법

  • 렌더링 내용은 return 문 안에 작성한다
  • 최상위 태그반드시 존재해야한다

최상위 태그는 반드시 존재해야한다

  • Virtual DOM에서 컴포넌트를 감지할 때, 하나의 돔트리로 구성되어 있어야 비교하는 데 효율적이다
  • 보통 div 태그를 많이 사용한다
		function App() {
		return (
			<div>
				<div>Hello React!</div>
				<p>만나서 반갑습니다.</p>
			</div>
		);
		}
  • 빈 태그 <></> 로 감쌀 수 도 있다

변수를 바인딩 할 수 있다

  • 변수를 중괄호{}로 감싸서 return 안에 삽입할 수 있다
		function App() {
			let title = '내일 할 일';
			return (
			<div>
				<h1>{title}</h1>
				<p>만나서 반갑습니다.</p>
			</div>
			);
		}

HTML의 클래스를 지정할 수 있다

  • react에서는 className 선택자 키워드를 통해 지정한다
		function App() {
			let title = '내일 할 일';
			return (
			<div className="bg">
				<h1>{title}</h1>
				<p>만나서 반갑습니다.</p>
			</div>
			);
		}

스타일 속성을 직접 설정할 수 있다

  • 태그 안에 style = {{속성명: '속성값'}}의 형태로 스타일을 설정할 수 있다
  • 태그 안의 속성명은 반드시 카멜케이스로 작성해야한다
		function App() {
			let title = '내일 할 일';
			return (
			<div className="bg">
				<h1>{title}</h1>
				<p style ={{color: 'red', fontSize: '30px'}}>만나서 반갑습니다.</p>
			</div>
			);
		}
  • 태그 사용 시 반드시 닫는 태그를 작성해야 한다

타입스크립트 적용

  • 함수형 컴포넌트의 타입 React.FC 를 사용한다
  • React.FCFuntional Component의 약자이며, 컴포넌트에 대한 명시적인 타입 정의를 제공한다
  • props의 타입 체크를 할 수 있다
  • props컴포넌트 간데이터를 전달하는 방법이다(매개 변수와 유사하다)
  • 부모 컴포넌트로부터 자식 컴포넌트로 데이터를 전달할 때 사용되는 객체이다

기본 형태

interface Props { 
	name: string; 
	age?: number; // 선택적 프로퍼티 
} 
const MyComponent: React.FC<Props> = ({ name, age }) => { 
	return ( 
  		<div>
      		안녕하세요, {name}! 당신의 나이는 {age}가 맞습니까?.
        </div>; 
    )
};

state

리액트는 일반 변수가 아닌, 상태 변수를 만들어서 데이터를 저장한다

  • const [post, setPost] = useState('미움받을용기');

state를 사용하는 이유

  • 일반변수를 사용했을 때 문제점
    • 지역 변수는 렌더링 간에 지속되지 않는다
      ( 리엑트는 두 번째로 렌더링할 때, 처음부터 컴포넌트를 다시 렌더링하기 때문에, 지역 변수의 변경이 고려되지 않는다)
    • 지역 변수의 변경은 렌더링을 발생시키지 않는다(Re-render 되지 않는다)
    • 즉, 지역 변수는 Re-render 발생시키지 않고, 다른 상태 변수에 의해 Re-render될 때, 초기화된다
    • 새로운 데이터로 컴포넌트를 다시 렌더링하도록 하는 것은 상태(state)와 속성(props) 변경 뿐이다
  • 따라서 변경이 필요한 변수가 있다면, useState Hook을 사용해야한다
    useState Hook은 두 가지 기능을 제공한다
    • 렌더링 간에 데이터를 유지하는 state variable(상태 변수)
    • 변수를 업데이트하고 리액트가 컴포넌트를 다시 렌더링하도록 trigger 역할을 하는 state setter function(상태 설정 함수)

useState Hook 사용 방법

import { useState } from 'react';

const {count, setCount} = useState(0);

const handleCountClick = (): void => {
	setCount(Count + 1);
};

return (
<div className="App">
	<div className="title-nav">
		<h1>{title}</h1>
	</div>
	<div className="list">
		<h3>
          {post[0]}
          <span onClick={handleCountClick}>❤️</span>
          {like}
		</h3>
		<p>발행 날짜</p>
	</div>
<div>
)
  • useState 안에 데이터의 초기 값을 설정
  • useState상태 변수setter 함수를 반환한다
  • setter 함수를 통해 상태 변수를 업데이트할 수 있다

state setter funcion의 동작 원리

  • 기존의 state와 변경된 state비교 검사한다
  • 바뀐 부분이 존재한다면, Re-render하고 바뀐 부분이 존재하지 않는다면, Re-render 하지 않는다

버튼을 클릭했을 때, 업데이트 되도록 하기

let [post, setPost] = useState(['고기사줄용기', '더마인드', '도둑맞은집중력']);

<button onClick={() => {
		let copyPost = post;
		copyPost[0] = '들이받을용기';
		setPost(copyPost);
}}>제목 변경
</button>

위와 같이 코드를 작성했을 때, 첫번째 요소가 변경되지 않는다. 이유가 멀까?

  • 상태 값은 불변성을 유지하면서 업데이트되어야한다
  • 상태 설정 함수에 전달되는 새로운 값은 이전 상태를 직접 변경하지 않고 새로운 상태 값으로 대체된다
  • 그러나 위의 그림을 살펴보면, postcopyPost같은 배열을 가리키는 것을 알 수 있다
  • 즉, 첫번째 요소가 '들이받을용기' 로 변경되었더라도 같은 배열이므로, 업데이트 되지 않는다
  • 새로운 배열이 상태로 설정될 때만 Re-render된다

그러면 첫번째 요소가 변경되도록 하기 위해서 어떻게 코드를 작성해야할까?

let [post, setPost] = useState(['고기사줄용기', '더마인드', '도둑맞은집중력']);

<button onClick={() => {
		let copyPost = [...post];
		copyPost[0] = '들이받을용기';
		setPost(copyPost);
}}>제목 변경
</button>
  • 위와 같이 코드를 작성한다면, 새로운 배열을 생성하고, 그 주소값을 copyPost가 참조한다

  • 위 그림처럼 새로운 배열이 상태로 설정됨으로, 컴포넌트를 Re-render 한다

컴포넌트(Component)

리액트 애플리케이션을 구성하는 기본 단위

  • 함수를 사용하는 목적, 방법과 거의 유사하다
  • 독립적이고 재사용 가능하며, 가독성을 높여 유지보수를 쉽게 해준다
  • 함수처럼 컴포넌트를 만든 후, 호출하여 사용한다
  • 컴포넌트는 html의 내용을 한 단위로 묶어놓은 것이다
  • 즉, 컴포넌트를 모듈화 할 수 있다

예시

const Detail: React.FC = () => {
	return (
		<div className="detail">
			<h3>제목</h3>
			<h4>내용</h4>
			<p>날짜</p>
		</div>
	);
};
  • return 안에는 하나의 태그로 시작하여 하나의 태그로 끝나야한다
  • react는 Detail 처럼 대문자로 시작하면, 컴포넌트로 인식한다

컴포넌트의 단점

  • 컴포넌트를 많이 사용할 수록 state 변수를 공유하기 불편하다
  • 컴포넌트는 함수와 마찬가지로 데이터를 직접 공유할 수 없다
  • 매개변수를 전달(props)하거나 전역변수(redux)를 사용하여 공유하는 방법이 있다

상세보기 Show / Hide 구현

  • return 안에는 if-else 를 작성할 수 없다
  • 대신 삼항 연산자를 사용 할 수 있다

삼항연산자 사용법

{
	조건식 ? 조건식 참이라면, 실행할 코드 : 조건식 거짓이라면, 실행할 코드
}
  • 위처럼 중괄호{} 안에 삼항 연산자를 작성해준다

예시

const [detail, setDetail] = useState(false);

const handleDetailClick = (): void => {
	detail == true ? setDetail(false) : setDetail(true)
}
...

<h3 onClick={handleDetailClick}>제목<h3>

{
	detail == true ? <Detail></Detail> : null
}
  • 제목을 클릭하면, 상세보기를 보여주거나 숨기도록 설정할 수 있다
profile
초보 개발자의 블로그입니다

0개의 댓글

관련 채용 정보