}

웹 시스템 개발 #React 기초편

학교 공부를 복습할 겸 적는 것이기에 내용이 부족할 수 있습니다.

 

부족한 것은 상관 없으나, 잘못된 부분이 발견된다면 지적해주시면 감사하겠습니다.

etc-image-0

 

JSX 또는 JavaScript XML은 UI가 어떻게 보여야 하는지 설명하기 위해 React에서 사용되는 JavaScript의 구문 확장입니다. JSX를 사용하면 JavaScript 코드와 동일한 파일에 HTML 구조를 작성할 수 있는 방법을 제공합니다. 

 

JSX 소개

  • JSX를 사용하면 JavaScript 코드에 HTML과 유사한 태그를 작성할 수 있습니다. 이러한 태그는 뒤에서 React.createElement 호출로 변환됩니다.
  • JavaScript로 컴파일되는 구문으로, 중괄호 {}로 묶어서 사용할 수 있습니다.
  • JSX는 선택사항이며 React를 사용하기 위해 필수는 아니지만, 대부분의 사람들은 UI를 정의할 때 직관적이고 선호합니다.

다음은 JSX 및 이에 상응하는 React.createElement 호출의 예입니다.

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

 

이 JSX 코드는 다음과 같이 컴파일됩니다.

const element = React.createElement(
  'h1',
  null,
  'Hello, ',
  name
);

 

 

 

JSX의 규칙

  • 단일 루트 요소 반환
    1. JSX 구성 요소는 단일 루트 요소를 반환해야 합니다.
    2. 프래그먼트는 <>...</> 또는 <React.Fragment>...</React.Fragment>로 작성할 수 있습니다.
<>
  <h1>Welcome to the site</h1>
  <p>This is a great place to be!</p>
</>

 

  • 모든 태그 닫기
    1. JSX에서 모든 태그는 img와 같은 요소에 대해 자체 닫는 태그로 닫혀 있거나 ul과 같은 컨테이너 요소에 대해 해당 닫는 태그로 적절하게 닫혀야 합니다.
<img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" />
<ul>
  <li>Invent new traffic lights</li> 
  <li>Rehearse a movie scene</li>
  <li>Improve the spectrum technology</li> 
</ul>

 

  • 중괄호로 표현
    1. JavaScript 표현식은 중괄호 {}로 묶어 JSX 내에 삽입할 수 있습니다.
    2. 인라인 스타일을 사용하거나 객체를 JSX 요소에 전달할 때 "이중 컬리"라고 하는 중괄호 안에 객체를 사용할 수 있습니다.
const TodoList = () => {
  const style = { backgroundColor: 'black', color: 'pink' };
  return (
    <ul style={style}> 
      <li>Improve the videophone</li>
    </ul>
  );
};

 

 

 

React Component란?

React의 Component를 통해 캡슐화되고 재사용 가능한 사용자 인터페이스 부분을 구축할 수 있습니다. 

 

컴포넌트란?

  • 기본 정의: 독립적이고 재사용 가능한 코드이며, JavaScript 함수와 동일한 목적을 수행하지만 별도로 작동하고 렌더링 함수를 통해 HTML을 반환합니다.
  • UI 블록 구축: React의 아키텍처는 Component  기반입니다. Component 를 사용하여 전체 화면, 페이지 또는 앱과 같은 복잡한 사용자 인터페이스를 구축할 수 있습니다.
  • 재사용 가능 및 캡슐화: 각 Component 는 자체 구조, 동작 및 스타일을 캡슐화합니다. 애플리케이션 전체에서 재사용할 수 있으므로 깔끔하고 유지 관리 가능한 코드를 작성할 수 있습니다.
function Welcome(props) {
  return <h1>Welcome Back, {props.name}</h1>;
}

 

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

 

Component 구성

  1. 다른 Component  참조
    • Component 는 출력에서 다른 Component 를 참조할 수 있습니다.
    • 예를 들어 React 애플리케이션에는 ButtonFormDialog 및 Screen과 같은 Component 가 있을 수 있으며, 각 Component 는 다른 Component 내에서 사용될 수 있습니다.
  2. props 사용
    • Props(properties의 약자)는 React에서 상위 구성 요소에서 하위 구성 요소로 데이터를 전달하는 기본 방법입니다.
    • Props는 읽기 전용이며 변경할 수 없습니다. 
    • 하위 구성 요소는 props를 단일 개체 인수로 받습니다.
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

 

구성요소 가져오기 및 내보내기

  1. 구성요소를 파일로 분리
    • 더 나은 재사용성을 위해 각 Component를 자체 파일에 배치할 수 있습니다.
  2. export 및 import
    • 자체 파일에서 Component를 내보내고 이를 사용하려는 다른 파일로 가져올 수 있습니다.
// utils.js
export function getImageUrl(person, size = 's') {
  return 'https://i.imgur.com/' + person.imageId + size + '.jpg';
}
import { getImageUrl } from './utils.js';

function Avatar(props) {
  return (
    <img
      className="avatar"
      src={getImageUrl(props.person)}
      alt={props.person.name}
      width={props.size}
      height={props.size}
    />
  );
}

export default function Profile() {
  return (
    <div>
      <Avatar size={50} person={{ name: 'Lin Lanying',  imageId: '1bX5QH6' }} />
    </div>
  );
}

 

 Avatar는 유틸리티 기능을 사용하여 이미지를 표시하는 구성 요소입니다. Profile은 Avatar를 사용하는 컴포넌트로, 특정 sizeperson 객체를 props로 전달합니다.

 

map() 메서드

렌더링하려는 데이터가 포함된 배열을 정의합니다. people은 문자열 배열이며, 각 문자열은 사람의 이름과 직업을 나타냅니다. 그 다음, JSX 노드에 매핑해줍니다.

 

map() 함수를 사용하여 배열의 각 요소를 반복하며 사람의 정보가 포함된 새로운 JSX 요소 <li>를 반환합니다.

 

마지막으로 구성 요소에서 JSX 목록 항목의 배열을 반환하고 이를 <ul> 요소로 래핑하여 순서가 지정되지 않은 목록을 만듭니다.

 

아래는 예시코드입니다.

const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario José Molina-Pasquel Henríquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

export default function List() {
  const listItems = people.map(person => <li key={person}>{person}</li>);
  return <ul>{listItems}</ul>;
}

 

이때 주의할 점은, 목록의 각 요소에 고유한 'key' prop을 제공해야한다는 점입니다.

etc-image-1
출력 화면

 

 

filter() 메서드

filter() 메소드를 사용하여 기준과 일치하는 요소만 포함하는 새 배열을 만듭니다.

이 경우 '직업'이 '화학자'인 사람만 포함합니다.

const people = [
  {
    id: 0,
    name: 'Creola Katherine Johnson',
    profession: 'mathematician',
    accomplishment: 'spaceflight calculations',
    imageId: 'MK3eW3A'
  },
  {
    id: 1,
    name: 'Mario José Molina-Pasquel Henríquez',
    profession: 'chemist',
    accomplishment: 'discovery of Arctic ozone hole',
    imageId: 'mynHUSa'
  },
  {
    id: 2,
    name: 'Mohammad Abdus Salam',
    profession: 'physicist',
    accomplishment: 'electromagnetism theory',
    imageId: 'bE7W1ji'
  }
];

export default function ChemistList() {
  const chemists = people.filter(person => person.profession === 'chemist');
  const listItems = chemists.map(chemist => (
    <li key={chemist.id}>
      {chemist.name}: {chemist.profession} - {chemist.accomplishment}
    </li>
  ));

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

 

Key

'key'는 목록이나 배열을 렌더링하고 업데이트하는 데 중요한 역할을 하며 주 목적은 목록의 각 요소를 고유하게 식별하도록 해주는 것입니다.

 

항목 순서가 변경될 수 있는 동적 목록에 특히 중요하며 React가 실제로 변경된 항목만 다시 렌더링하여 성능을 향상시킬 수 있기 때문입니다.

 

const people = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];

return (
  <ul>
    {people.map(person => (
      <li key={person.id}>{person.name}</li>
    ))}
  </ul>
);

 

 

주의

<React.StrictMode>
  <App />
</React.StrictMode>

 

엄격한 모드를 사용하게 되면 의도적으로 구성 요소를 두 번 렌더링하게 됩니다. 개발 모드에서만 발생하며 프로덕션 빌드에서는 발생하진 않지만, 부작용같은 의도하지 않은 동작을 찾아내기 위함입니다.

 

아래 코드와 같이 사용하게 되면 외부 변수 수정으로 인해 버그와 비효율적인 렌더링으로 이어질 수 있습니다.

let guest = 0; 

function Cup() {
  guest = guest + 1;
  console.log(guest)
  return <h2>Tea cup for guest #{guest}</h2>; 
}

function App() {
  return (
    <>
    <Cup /> 
    <Cup /> 
    <Cup />
    </>
  );
}

etc-image-2
의도치 않은 버그

 

따라서, 아래와 같은 코드로 작성을 해야 합니다.

function Cup({guest}) {
  return <h2>Tea cup for guest #{guest}</h2>; 
}

etc-image-3
의도된 결과