기술/React.js

[문서] 리액트 공식문서 톱아보기: 기본 문법(빠른 시작 가이드)

빔네모 2024. 10. 27. 23:50

React 앱은 컴포넌트로 구성된다.

컴포넌트는 마크업을 반환하는 자바스크립트 함수로 작성한다.

  • 컴포넌트 명명은 대문자로 시작한다. ex) MyButton
  • JSX 문법이므로,  <br/> 처럼 태그를 닫아줘야 한다
  • 여러 개의 JSX 태그를 반환할 수 없으므로 <div> ... </div> 와 같이 부모로 감싸주어야 한다.
  •  html문법을 jsx로 변환해주는 사이트: https://transform.tools/html-to-jsx
function MyButton() {
  return (
    <button>I'm a button</button>
  );
}

//컴포넌트 생성

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

//다른 컴포넌트 안에 중첩

스타일 추가하기

React에서는 class가 아닌 className으로 CSS 클래스를 지정한다.

<img className="avatar" />

/* In your CSS */
.avatar {
  border-radius: 50%;
}

데이터 표시하기

중괄호를 사용하여 태그안에 일부 변수를 삽입하거나 어트리뷰트 값을 설정할 수 있다.

*주의 : 스타일 값이 자바스크립트 변수에 의존할때는 {} 객체로 전달해야 된다.

//인라인 스타일은 이렇게 작성해요
<div style={{ color: userColor }}>

// 첫 번째 중괄호 {} : 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
        }}
      />
    </>
  );
}

조건부 렌더링

if문을 사용하여 나태낼 수 있지만 더 간결하게 표현하기 위해 삼항 연산자를 주로 사용한다.

//if문 사용
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);
//삼항연산자
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

else 분기가 필요하지 않다면 && 연산자로 나타낼 수 있다.

<div>
  {isLoggedIn && <AdminPanel />}
</div>

리스트 렌더링하기

리스트 같이 반복되는 컴포넌트를 보여주기 위해서는 for문이나 map() 을 이용한다. 

//다음과 같은 데이터가 있다고 가정
const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

//해당 제품 배열을 <li> 항목 배열로 반환
const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);
중요!! 반복되는 컴포넌트를 반환할때는 key를 설정하자. React가 목록이 변경될 때 어떤 항목이 바뀌었는지 빠르게 찾을 수 있어 성능 최적화에 도움이 된다. (key는 겹치지 않는 고유한 값으로 해야 된다.)

이벤트에 응답하기

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

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

  return (
  //이벤트 선언
    <button onClick={handleClick}> 
      Click me
    </button>
  );
}

중요한 점:

  • onClick={handleClick} (O)
  • onClick={handleClick()} (X)

왜냐하면:

  • handleClick: "이 함수를 나중에 클릭할 때 실행해줘"
  • handleClick(): "이 함수를 지금 당장 실행해!"

쉽게 말해서, React한테 "버튼 클릭하면 이 함수 실행해줘"라고 함수를 건네주는 것!

화면 업데이트하기

버튼을 클릭했을때 클릭된 수 만큼 변하는 값을 화면에 표시해주고 싶다면? 컴포넌트에 state를 추가한다.

import { useState } from 'react';

useState로부터 현재 state (count)와 이를 업데이트할 수 있는 함수(setCount)를 얻을 수 있다.

const [값, 값을바꾸는함수] = useState(초기값);

어떤 이름으로도 지정할 수 있지만 [something, setSomething]으로 작성하는 것이 일반적이다.

 useState의 특징은 다음과 같다.

 

  • 컴포넌트가 리렌더링되어도 값이 유지
  • 값이 변경되면 화면이 자동으로 업데이트
  • 여러 개의 상태를 동시에 관리할 수 있음(단, 너무 많이 관리할 경우 코드가 복잡해질 수 있음)

 

function MyButton() {
  const [count, setCount] = useState(0);

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

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );

count 값은 초기값을 0으로 설정했기에 처음에는 0으로 뜬다.

버튼을 누르면 값을 바꾸는 set 기능으로 인해 count+1 된 값으로 변경된다. 

Hook 사용하기

useState 처럼 use ~ 로 시작되는 리액트의 특별한 함수들을 hook이라고 하는데, 기존의 훅을 조합하여 자신만의 훅을 만들 수도 있다. 리액트에서 제공하는 훅은  https://ko.react.dev/reference/react/hooks 여기서 확인 가능!

 

Hook을 사용할 때는 몇가지 규칙을 지켜야 된다.

 

  • 컴포넌트 최상위에서만 호출
  • 반복문, 조건문 안에서 사용 금지(반복에서 사용하고 싶다면 컴포넌트로 추출하여 넣기)

컴포넌트 간에 데이터 공유하기 

 

 

컴포넌트가 위 사진처럼 구성된 경우, 한쪽에서 카운트를 올리면 다른 한쪽 카운트는 변하지 않는다.

데이터를 공유하고 같이 업데이트 하기 위해서는 어떻게 해야 될까?

MyButton 컴포넌트가 동일한 count를 표시하고 함께 업데이트하려면, state를 상위에서 사용해야 된다.

그 다음 상위에서 사용된 state 값을 하위요소인 MyButton 에게 내려주면 된다.

코드로 표현하면 다음과 같다. 이렇게 부모 컴포넌트에서 자식 컴포넌트로 어떤 값을 내려주는 것을 props 라고 한다.

 

  • 읽기 전용 (자식이 받은 props를 직접 수정할 수 없음)
  • 부모 → 자식 한 방향으로만 전달
  • 객체, 함수 등 모든 타입의 데이터 전달 가능

 

// 부모 컴포넌트
function ParentComponent() {
  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>
  );
}
  1. 버튼 클릭 → handleClick 함수 실행
  2. setCount(count + 1)로 숫자 증가
  3. 증가된 숫자가 props로 두 버튼에 전달됨
  4. 두 버튼이 같은 숫자를 보여줌

부모 컴포넌트에서 state를 관리하니까 자식 컴포넌트들이 같은 값을 공유할 수 있다.