웹 시스템 개발 #React 기초편

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

 

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


 

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을 제공해야한다는 점입니다.

출력 화면

 

 

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 />
    </>
  );
}

의도치 않은 버그

 

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

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

의도된 결과