본문 바로가기

이것저것 스터디📚/React - 공식 문서

React 공식문서 - Quick Start

Creating and nesting components(컴포넌트 생성 및 중첩하기)

 

React 앱은 컴포넌트로 만들어진다. React 컴포넌트는 마크업을 반환하는 JavaScript 함수로써, 고유한 로직과 모양을 가진 UI(사용자 인터페이스)의 일부이며, 버튼만큼 작을 수도 있고 전체 페이지만큼 클수도 있다.

 

* MyButton이라는 컴포넌트 선언

function MyButton () {
  return (
    <button>I'm a button</button>
  );
}

* 선언된 MyButton 컴포넌트를 다른 컴포넌트에 중첩

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
    </div>
  );
}

위의 예제와 같이 React 컴포넌트는 대문자로 시작하고, HTML 태그는 소문자로 시작한다.

 

* React 컴포넌트는 항상 대문자로 시작해야 하지만, 함수명이 대문자일 필요는 없다. 다만 JSX 안에서 컴포넌트가 사용될 때에는 반드시 대문자로 시작해야 한다.


Writing markup with JSX(JSX로 마크업 작성하기)

 

React 프로젝트에서 JSX는 선택 사항이지만 대부분의 React 프로젝트는 편의성을 위해 JSX를 사용한다. JSX는 HTML보다 엄격하기 때문에 <br / >과 같은 태그를 닫아야 하고, 여러개의 JSX 태그를 반환할 수 없기 때문에 <div>...</div> 또는 빈 <>...</> 래퍼와 같이 하나의 공유 부모로 감싸야한다.


Adding styles(스타일 추가하기)

 

리액트에서는 별도의 CSS 파일에 CSS 규칙을 작성하고 className으로 CSS클래스를 지정한다.

.avatar {
  border-radius: 50%;
}
<img className="avatar" />

React는 CSS 파일을 추가하는 방법 중 가장 간단한 방법은 HTML에 <link> 태그를 추가하는 방법이 있고, 빌드 도구나 프레임워크를 사용하는 경우 CSS 파일을 추가하는 다양한 방법이 있다.(https://react.vlpt.us/styling/)


Displaying data(데이터 표시하기)

 

JSX를 사용하면 JavaScript에 마크업을 넣을 수 있고, 중괄호를 사용하면 JavaScript로 "이스케이프"할 수 있다. JavaScript로 "이스케이프"하기 위해서는 따옴표 대신 중괄호를 사용해야 한다.

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar" // "avatar"라는 문자열을 CSS 클래스로 전달
        src={user.imageUrl} // JavaScript의 user.imageUrl 변수 값
        alt={'Photo of ' + user.name} // 문자열 연결과 같이 복잡한 표현식
        style={{
          width: user.imageSize,
          height: user.imageSize
        }} // style={} JSX 중괄호 안에 있는 일반 {} 객체
      />
    </>
  );
}

Conditional rendering(조건부 렌더링)

 

React에서는 조건을 작성하기 위한 특별한 문법은 없다. 대신 일반 JavaScript 코드와 동일한 기법을 사용할 수 있다.

1. if문의 사용

let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

2. 조건부 (삼항) 연산자 사용

// if와 달리 JSX 내부에서 작동
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

3. 논리 && 구문 사용 

// else 분기가 필요하지 않을 경우 사용
<div>
  {isLoggedIn && <AdminPanel />}
</div>

Rendering lists(목록 렌더링)

 

React에서 컴포넌트 목록을 렌더링하려면 for loog 및 배열 map() 함수를 사용할 수 있다.

const products = [
  { title: 'Cabbage', isFruit: false, id: 1 },
  { title: 'Garlic', isFruit: false, id: 2 },
  { title: 'Apple', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

이때, <li>에 key 속성이 있는데, key 속성은 목록의 각 항목에 대해, 해당 항목을 고유하게 식별하는 문자열 또는 숫자를 전달해야하며, React는 나중에 항목을 삽입, 삭제 또는 재정렬할 때 어떤 일이 일어났는지 이해하기 위해 key를 사용한다.


Responding to events(이벤트에 응답하기)

 

React에서는 컴포넌트 내부에 이벤트 핸들러 함수를 선언하여 이벤트에 응답할 수 있다.

function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

이벤트 핸들러 함수를 handlerClick()과 같이 호출하는 것이 아닌, 전달만 하는 것이고 사용자가 버튼을 클릭할 때 이벤트 헨들러를 호출하는 것이다.


Updating the screen(화면 업데이트하기)

 

컴포넌트가 특정 정보를 "기억"하여 표시하기를 원하는 경우에는 컴포넌트 내부에 state 변수를 선언할 수 있다. useState를 통해서 현재 state와 state를 업데이트할 수 있는 함수를 얻을 수 있다.

 

예를들어, 여러 state가 있는 경우에는 각각의 state는 고유하며 다른 state에 영향을 주지 않는다.


Using Hooks(훅 사용하기)

 

'use'로 시작하는 함수를 훅(Hook)이라고 한다. React Hooks는 React의 함수형 컴포넌트 내에서만 호출할 수 있고, Hooks를 이용한 함수(예를 들어, useState, useEffect 등)는 함수 컴포넌트의 바디에서 직접 호출되어야 한다.

 

하지만, 조건문이나 반복문에서 직접 Hooks를 호출하는 것은 React의 Hook 사용 규칙에 위배되고, 컴포넌트가 다시 렌더링될 때 Hooks의 호출 순서가 바뀔 수 있어, 예상치 못한 버그를 유발할 수가 있다.

// 조건문 내부에서 Hook을 사용하는 경우(권장되지 않는 방식)
if (condition) {
  const [state, setState] = useState(initialState);
  ...
}

대신, 조건에 따라 상태를 설정하거나, 반복적으로 상태를 설정하고 싶다면, 이를 수행하는 별도의 컴포넌트를 만들고 그 안에서 Hooks를 호출하도록 해야한다.

// 별도의 컴포넌트를 만드는 방식
function MyComponent() {
  if (condition) {
    return <ComponentWithState />;
  } else {
    ...
  }
}

function ComponentWithState() {
  const [state, setState] = useState(initialState);
  ...
}

Sharing data between components(컴포넌트 간 데이터 공유하기)

 

React에서 두 개의 컴포넌트가 동일한 state를 표시하고 함께 업데이트하려면 두 개의 컴포넌트를 모두 포함하는 가장 가까운 컴포넌트로 state를 이동해야한다.

예를들어, 위 그림과 같이 count라는 동일한 state를 각각의 MyButton 컴포넌트에서 표시를 하는 경우, 두 개의 버튼 중에 하나를 클릭하면, MyApp의 count가 변경되고, count를 표시하는 두 개의 MyButton가 모두 변경된다.

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

* 참고 : React 공식문서(https://react-ko.dev/learn)