프론트엔드(Web)/React

리액트 - 컴포넌트 기본문법(컴포넌트 생성, props, children, 조건부 및 반복 , 이미지 렌더링)

만능 엔터테이너 2024. 8. 25. 12:32
728x90
반응형
SMALL


any 타입: 자바스크립트에 존재하는 모든 값을 오류 없이 받을 수 있음. any로 지정한 타입에 임의의 값을 할당하더라도 오류가 발생하지 않습니다.

let state: any

state ={value:0}
state = 100;
state = "hello world!"
state.foo.bar = () => console.log("this is any type")

 

타입이 명시되지 않은 any타입을 변수에 할당하는 것은 지양해햐 할 패턴!

 

type과 interface :객체를 입력할 때는 주로 type과 interface 형태로 지정합니다. 중괄호{}를 사용한 객체 리터럴 방식으로 타입을 매번 일일이 지정하기에 중복되는 요소가 많기에 지정합니다.


props

 

리액트에서 ‘props’는 컴포넌트 간에 데이터를 전달하는 방법입니다.

‘props’는 부모 컴포넌트가 자식 컴포넌트에 전달하는 읽기 전용 데이터입니다.

‘props’는 컴포넌트가 상위 컴포넌트로부터 받는 입력값이라고 할 수 있으며, 컴포넌트는

이를 이용해 렌더링 결과를 동적으로 변경할 수 있습니다.

문법

<Component 속성={값} />

 

props의 주요 특징

  1. 읽기 전용(Read-Only): props는 자식 컴포넌트 내부에서 수정할 수 없습니다. 자식 컴포넌트는 부모로부터 전달받은 props를 수정하지 않고 그대로 사용해야 합니다. 이러한 특성은 React의 단방향 데이터 흐름(one-way data flow)을 유지하는 데 중요한 역할을 합니다.
  2. 부모-자식 간 데이터 전달: props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 데 사용됩니다. 부모 컴포넌트에서 자식 컴포넌트를 렌더링할 때, 속성(attribute) 형태로 데이터를 전달할 수 있습니다.
  3. 컴포넌트 재사용성: props를 사용하면 하나의 컴포넌트를 다양한 데이터로 여러 번 재사용할 수 있습니다. 이를 통해 컴포넌트를 보다 효율적으로 작성할 수 있습니다.

props 사용 방법

기본 사용법

아래 예제에서는 Greeting 컴포넌트가 name이라는 props을 받아서 인사 메시지를 출력합니다.

Greeting.tsx

const Greeting = (props: { name: string }) => {
  return <h1>Hello, {props.name} </h1>;
};

export default Greeting;

 

App.tsx

import Greeting from "./components/Greeting";

const App = () => {
  return (
    <div>
      <Greeting name="철수" />
      <Greeting name="영희" />
      <Greeting name="바둑이" />
    </div>
  );
};

export default App; 

표현식 사용법

이때, name 속성을 전달할 때는 아래처럼 표현식을 해도 됩니다.

App.tsx

...
<Greeting name={"철수"} />
<Greeting name={"영희"} />
<Greeting name={"바둑이"} />
...

 

구조 분해 할당 사용

컴포넌트에서 props를 받을 때 아래처럼 구조 분해 할당을 사용해도 됩니다.

Greeting.tsx

const Greeting = ({ name }: { name: string }) => {
  return <h1>Hello, {name} </h1>;
};
export default Greeting;

여러 개의 Props 전달하기

UserCard.tsx

const UserCard = ({
  name,
  age,
  gender,
}: {
  name: string;
  age: number;
  gender: string;
}) => {
  return (
    <div>
      <p>{name}</p>
      <p>{age}</p>
      <p>{gender}</p>
    </div>
  );
};

export default UserCard;

App.tsx

import UserCard from "./components/UserCard";

const App = () => {
  return (
    <div>
      <UserCard name="철수" age={19} gender={"male"} />
      <UserCard name="영희" age={19} gender={"female"} />
      <UserCard name="바둑이" age={10} gender={"male"} />
    </div>
  );
};

export default App;

이벤트 전달

props로 이벤트(함수)를 전달할 수 있습니다.

App.tsx

import UserCard from "./components/UserCard";

const App = () => {
  const onClickHandler = (name: string, age: number, gender: string) => {
    alert(`${name}, ${age}, ${gender === "male" ? "남자" : "여자"}`);
  };
  return (
    <div>
      <UserCard
        name="철수"
        age={19}
        gender={"male"}
        onClickHandler={onClickHandler}
      />
      <UserCard
        name="영희"
        age={19}
        gender={"female"}
        onClickHandler={onClickHandler}
      />
      <UserCard
        name="바둑이"
        age={10}
        gender={"male"}
        onClickHandler={onClickHandler}
      />
    </div>
  );
};

export default App;

UserCard.tsx

const UserCard = ({
  name,
  age,
  gender,
  onClickHandler,
}: {
  name: string;
  age: number;
  gender: string;
  onClickHandler: (name: string, age: number, gender: string) => void;
}) => {
  return (
    <div>
      <p>{name}</p>
      <p>{age}</p>
      <p>{gender}</p>
      <button onClick={() => onClickHandler(name, age, gender)}>출력</button>
    </div>
  );
};

export default UserCard;

Children

Children Props

React에서 children prop는 컴포넌트의 속성 중 하나로, 컴포넌트의 자식 요소들을 포함합니다. 이를 통해 부모 컴포넌트는 자식 컴포넌트를 동적으로 렌더링할 수 있습니다. children prop은 모든 React 컴포넌트에 기본적으로 존재하며, 주로 컴포넌트 간의 구성 요소를 더 쉽게 재사용하고, 동적으로 컨텐츠를 전달할 때 유용합니다.

 

기본 사용 예제

components/Wrapper.tsx

const Wrapper = (props: { children: React.ReactNode }) => {
  return <div className="box">{props.children}</div>;
};

export default Wrapper;

 

여기서 children의 타입을 지정하려고 할 때, 항상 React.ReactNode로 고정적으로 지정해주어야 합니다. 이 부분은 암기!!


조건부 렌더링

정의

리액트에서 조건부 렌더링(Conditional Rendering)은 특정 조건에 따라 컴포넌트나 요소를 렌더링하는 것을 의미합니다. 자바스크립트의 조건문을 사용하여, 특정 조건이 참일 때만 컴포넌트를 렌더링하거나, 조건에 따라 다른 컴포넌트를 렌더링할 수 있습니다. 이를 통해 효율적으로 UI를 관리할 수 있습니다.

방법

if 문을 사용한 조건부 렌더링

전통적인 if 문을 사용하여 조건부 렌더링을 구현할 수 있습니다. 이 방법은 특정 조건이 참일 때만 컴포넌트를 반환하도록 합니다.

const App = () => {
  const isLogin = false;

  if (isLogin) {
    return (
      <>
        <h1>Not Login!</h1>
      </>
    );
  }

  return (
    <>
      <h1>Hello, Not Login!</h1>
    </>
  );
};
export default App;

삼항 연산자를 사용한 조건부 렌더링

삼항 연산자는 짧은 조건부 렌더링을 할 때 유용합니다.

const App = () => {
  const isLogin = true;
  return <>{isLogin ? <h1>Hello, Login!</h1> : <h1>Hello, Not Login!</h1>}</>;
};
export default App;

논리 연산자 &&를 사용한 조건부 렌더링

논리 연산자 &&를 사용하면 조건이 참일 때만 특정 컴포넌트를 렌더링할 수 있습니다.

const App = () => {
  const isLogin = false;
  return (
    <>
      {isLogin ? <h1>Hello, Login!</h1> : <h1>Hello, Not Login!</h1>}
      {!isLogin && <div>Login Failed</div>}
      {isLogin && <div>Login Successed</div>}
    </>
  );
};
export default App;

 

즉시 실행 함수를 사용하여 조건부 렌더링을 구현하기

const App = () => {
  const isLogin = true;

  return (
    <>
      {(() => {
        if (isLogin) {
          return (
            <>
              <h1>Hello, Login!</h1>
              <button>Logout</button>
            </>
          );
        } else {
          return (
            <>
              <h1>Hello, Not Login!</h1>
              <button>Login</button>
            </>
          );
        }
      })()}
    </>
  );
};

export default App;

반복 렌더링

정의

리액트에서 반복 렌더링은 특정 컴포넌트 요소를 반복적으로 출력하는 렌더링 방식을 말합니다.

방법

문자열 배열은 렌더링

문자열 배열 items를 map 메서드로 반복하여, 각 항목을 <li> 요소로 렌더링합니다. key 속성은 배열 항목의 고유성을 보장하기 위해 사용됩니다.

import React from 'react';

const App = () => {
  const items = ['Apple', 'Banana', 'Cherry'];

  return (
    <div>
      <h1>Fruits</h1>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

 

객체 배열 렌더링

객체 배열을 렌더링하는 경우, 객체의 각 속성에 접근하여 렌더링할 수 있습니다.

import React from 'react';

const App = () => {
  const users = [
    { id: 1, name: 'John Doe', age: 30 },
    { id: 2, name: 'Jane Smith', age: 25 },
    { id: 3, name: 'Alice Johnson', age: 28 }
  ];

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>
            {user.name} - Age: {user.age}
          </li>
        ))}
      </ul>
    </div>
  );
};
export default App;

 

컴포넌트와 함께 사용하기

리액트에서는 반복 렌더링을 할 때 컴포넌트를 활용하여 보다 복잡한 구조를 만들 수 있습니다.

import React from 'react';

// UserCard 컴포넌트
const UserCard = ({ user }) => (
  <div>
    <h2>{user.name}</h2>
    <p>Age: {user.age}</p>
  </div>
);

const App = () => {
  const users = [
    { id: 1, name: 'John Doe', age: 30 },
    { id: 2, name: 'Jane Smith', age: 25 },
    { id: 3, name: 'Alice Johnson', age: 28 }
  ];

  return (
    <div>
      <h1>User Profiles</h1>
      <div>
        {users.map(user => (
          <UserCard key={user.id} user={user} />
        ))}
      </div>
    </div>
  );
};
export default App;

반복 렌더링을 할 때, key를 인덱스 번호로 사용하지 않도록 주의해주세요.


컴포넌트에 이미지 넣기(렌더링)

src 하위에 폴더에 넣기

src 폴더 하위에 이미지 파일을 원하는 위치에 넣고 import 문법으로 이미지를 불러와서 처리하는 방법을 말합니다.

☝ // 이미지 파일의 경로가 src/assets/images/react-logo.svg 일 경우

 

img 태그에 넣기

import reactIcon from "./assets/images/react-logo.svg";
const App = () => {
  return (
    <>
      <img src={reactIcon} alt="" width={100} />
    </>
  );
};
export default App;

 

css에서 넣기

.logo {
  background-image: url("../images/react-logo.svg");
}
<div className="logo w-40 h-40 bg-cover"></div>

 

public 폴더에 넣기

public 폴더에 이미지를 넣으면 공용 폴더이기 때문에 상대 경로로 접근이 가능합니다. 아래는 public/nine.jpg에 이미지를 넣었을 때 사용법입니다.

const App = () => {
  return (
    <>
      <img src="/nine.jpg" alt="" />
    </>
  );
};
export default App;

const App = () => {
  return (
    <>
      <div
        className="w-40 h-40 bg-cover"
        style={{ backgroundImage: `url(./nine.jpg)` }}
      ></div>
    </>
  );
};
export default App;

public vs src 하위

리액트에서 이미지는 public 폴더 또는 assets 폴더에 넣어서 활용할 수 있습니다. 학습하면서 살펴봤던 것처럼 어디에 넣어서 활용하느냐에 따라서 활용 방법도 달라집니다. 그러면 어떤 방식을 선택해서 이미지를 활용하는 게 좋을까요?

public

우선 public 폴더에 저장하면 공용이 됩니다. 요컨대, 나중에 서비스를 배포하더라도 https://서비스도메인/sample.png 처럼 도메인을 통한 접근이 가능하다는 이야기입니다.

assets

assets 폴더에 저장된 이미지는 공개적으로 노출되지 않습니다. 오직 리액트 시스템 내부에서만 활용 가능합니다. 또한, 코드 파일에서 import 구문으로 불러오면 리액트가 빌드 프로세스 과정 중에 자동으로 이미지를 최적화 해주며, 웹 사이트에 제공하기 직전에 public 폴더에 삽입됩니다.

그래서 결론은?

빌드 프로세스에 의해서 처리되지 않는 이미지는 public 폴더에 넣어줍니다. 주로 파피콘 같은 이미지를 public 폴더에 넣습니다. 반면 컴포넌트 내에서 사용되는 이미지는 일반적으로 src/assets 폴더 하위에 넣는 게 좋습니다.

 

[스나이퍼 팩토리 2기 과정]

본 학습 자료 및 코드는 수코딩님의 자료를 이용하였습니다. [수코딩(https://www.sucoding.kr)] 출처

728x90
반응형
LIST