본문 바로가기

프로그래밍 언어/JavaScript

[React] 공식 문서 - 학습하기 - 빠르게 시작하기

목차

  • 개요
  • 학습내용
    • 컴포넌트 생성 및 중첩하기
    • JSX로 마크업 작성하기
    • 스타일 추가하기
    • 데이터 표시하기
    • 조건부 렌더링하기
    • 리스트 렌더링하기
    • 이벤트에 응답하기
    • 화면 업데이트하기
    • Hook 사용하기
    • 컴포넌트 간에 데이터 공유하기

 

개요

공식 문서를 통해 react 개념을 학습하려고 한다.

중요하다고 생각하는 부분을 기록하면 더 기억에 오래 남을 것 같아서 게시글로 작성한다.

정확한 내용은 문서 참조하기!

 

빠르게 시작하기 – React

The library for web and native user interfaces

ko.react.dev

 

학습하기

컴포넌트 생성 및 중첩하기 
  • React 앱은 컴포넌트로 구성
  • 컴포넌트: 고유한 로직과 모양을 가진 UI(사용자 인터페이스)의 일부. 버튼, 페이지 ...
  • React 컴포넌트: 마크업을 반환하는 자바스크립트 함수
function MyButton() {
  return (
    <button>I'm a button</button>
  );
}
  • React 컴포넌트의 이름은 항상 대문자로 시작 <-> HTML 태그는 소문자로 시작
  • 컴포넌트는 컴포넌트 안에 중첩될 수 있다
function MyButton() {
  return (
    <button>
      I'm a button
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}
  • export default 키워드: 파일의 기본 컴포넌트를 지정

 

JSX로 마크업 작성하기
// JSX
const element = <h1>Hello, world!</h1>;
  • JSX(JavaScript XML): JavaScript를 확장한 문법
    • JSX는 HTML보다는 JavaScript에 가깝기 때문에,
       React DOM은 HTML 어트리뷰트 이름 대신 camelCase 프로퍼티 명명 규칙을 사용
       ex) class -> className, tabindex -> tabIndex
  • 태그를 닫아야 함. ex) <br />
  • 컴포넌트는 여러 개의 JSX 태그를 반환할 수 없음!
    <div>...</div> 또는 빈 <>...</> 래퍼와 같이 공유되는 부모로 감싸야 함
function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}

 

스타일 추가하기
  • className으로 CSS 클래스를 지정. HTML의 class 어트리뷰트와 동일한 방식으로 동작
  • React는 CSS 파일 추가하는 방법을 특정하게 규정하지 않음

 

데이터 표시하기
  • JSX에서는 중괄호 { } 를 사용해 JavaScript 표현식을 삽입할 수 있음.
    => HTML처럼 보이는 JSX 문법 안에서 다시 JavaScript 코드로 전환( => escape Into JavaScript ) 하는 동작
return (
  <h1>
    {user.name}
  </h1>
);
  • JSX 어트리뷰트에서 따옴표"" 대신 중괄호{}를 사용하여 “자바스크립트로 이스케이프(escape Into JavaScript)” 가능
return (
  <img
    className="avatar" // "avatar" 문자열을 CSS로 전달
    src={user.imageUrl} // 자바스크립트 user.imageUrl 변수 값을 읽은 다음 해당 값을 src 어트리뷰트로 전달
  />
);
  • JSX 중괄호 안에 문자열 연결과 같이 더 복잡한 표현식을 넣을 수도 있음
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"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }} // style={{}}은 특별한 문법이 아니라 style={ } JSX 중괄호 안에 있는 일반 {} 객체
      />
    </>
  );
}

 

조건부 렌더링하기
  • React에서 조건문을 작성하는 데에는 특별한 문법이 필요 없음
    일반적인 자바스크립트 코드를 작성할 때 사용하는 것과 동일한 방법을 사용
  • ex-1) if을 사용. 조건부로 JSX를 포함
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);
  • ex-2) 조건부 삼항 연산자 사용. JSX 내부에서 동작
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>
  • ex-3) && 연산자 사용
<div>
  {isLoggedIn && <AdminPanel />}
</div>

 

리스트 렌더링하기
  • 컴포넌트 리스트를 렌더링하기 위해서는 for문 map() 함수와 같은 자바스크립트 기능을 사용
  • <li>key 어트리뷰트가 있는 것에 주목!
    목록의 각 항목에 대해, 형제 항목 사이에서 해당 항목을 고유하게 식별하는 문자열 또는 숫자를 전달해야 함
    React는 나중에 항목을 삽입, 삭제 또는 재정렬할 때 어떤 일이 일어났는지 알기 위해
    key를 사용
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>
  );
}

 

이벤트에 응답하기
  • 컴포넌트 내부에 이벤트 핸들러 함수를 선언(호출X)하여 이벤트에 응답할 수 있음
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}> // React는 사용자가 버튼을 클릭할 때 이벤트 핸들러를 호출
      Click me
    </button>
  );
}

 

화면 업데이트하기
  • 컴포넌트가 특정 정보를 “기억”하여 표시하기를 원하는 경우 컴포넌트에 state를 추가하면 됨
// 1. React에서 useState를 가져옴
import { useState } from 'react';

function MyButton() {
  // 2. 컴포넌트 내부에 state 변수를 선언 
  // useState로부터 현재 state(count)와 이를 업데이트할 수 있는 함수(setCount)를 얻을 수 있음
  // 이름은 [something, setSomething]으로 작성하는 것이 일반적
  // useState()에 0을 전달했기 때문에 처음의 count 값은 0
  const [count, setCount] = useState(0);

  function handleClick() {
    // 3. state를 변경하고 싶다면 setCount()를 실행하고 새 값을 전달
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  ); // 4. 이 버튼을 클릭하면 카운터가 증가
}

 

 

Hook 사용하기
  • use로 시작하는 함수Hook이라고 함
  • useState는 React에서 제공하는 내장 Hook
  • 다른 내장 Hook은 API 참고서에서 찾아볼 수 있음
  • 기존의 것들을 조합하여 자신만의 Hook을 작성할 수도 있음
  • Hook은 다른 함수보다 더 제한적임
  • 컴포넌트(또는 다른 Hook)의 "상단"에서만 Hook을 호출할 수 있음
  • 조건이나 반복에서 useState를 사용하고 싶다면 새 컴포넌트를 추출하여 그곳에 넣어야 함

 

컴포넌트 간에 데이터 공유하기
  • state를 위(부모)로 이동함으로써 컴포넌트 간에 state를 공유

import { useState } from 'react';

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

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

  // MyApp 컴포넌트는 count state와 handleClick 이벤트 핸들러를 포함하며
  // 이 두 가지를 각 버튼에 props로 전달
  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

// 부모 컴포넌트에서 전달 받은 props를 읽도록 처리
function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}