# 당장 개발할 때 알아두면 좋은 리액트 지식들 #1

> 안녕하세요,
> 리버스마운틴 개발자 양현빈입니다. ☺️
> Flutter로 티키타카 웹 서비스 개발을 함께했습니다.
> Flutter 웹 개발 경험과 더불어 React로 새롭게 개발하는 과정에서의 이야기들을 블로그에 공유할 예정이에요.
> 
> Github: [https://github.com/YangHyeonBin](https://github.com/YangHyeonBin) 
> Linkedlin: [https://www.linkedin.com/in/hyeonbin-yang-25598427a/](https://www.linkedin.com/in/hyeonbin-yang-25598427a/) 
> Email: hb@reversemountain.co.kr

## Overview

React UI 개발에 필요한 기본적인 개념과 문법을 설명합니다.

당장 React로 개발을 진행해야 해서, 팀원들과 공유할 목적으로 작성했어요. 그렇다보니 체계적인 순서를 갖추진 않았습니다.

간단히 훑어보시고, 체계적인 학습을 원하시면 공식 문서를 참고하실 것을 추천드려요! ([한국어]([https://ko.react.dev/learn/describing-the-ui](https://ko.react.dev/learn/describing-the-ui)), [영어]([https://react.dev/learn/describing-the-ui](https://react.dev/learn/describing-the-ui) ))

이 글에서 다루는 내용은 아래와 같습니다.:

- 확장자: `.ts` vs `.tsx`?

- `JSX`

- 리액트 컴포넌트

- State

- `import`, `export`

# 1. 확장자: `.ts` vs `.tsx`?

- `.ts`: TypeScript 확장자

- `.tsx`: TypeScript인데, **jsx** 문법을 사용 가능하게 하는 확장자

⇒ **jsx**를 사용할 거라면, 즉 **리액트 컴포넌트를 개발**할 거라면 `.tsx`를, 그냥 TypeScript만 사용하는 로직을 개발할 거라면 `.ts`를 사용
(리액트 컴포넌트 코드 작성하는데 확장자가 `.ts`일 경우 에러 발생)

# 2. `JSX` 

- JavaScript XML. 자바스크립트의 확장 문법(syntax extension).

- JavaScript 또는 TypeScript 언어를 사용하는 `.jsx`나 `.tsx` 파일에서 **HTML과 같은 마크업 코드**를 작성할 수 있게 함

- 하나의 화면을 개발하는데 HTML, (CSS,) JavaScript 세 파일을 만들어야 했던 불편함 해소

- 수많은 사용자 인터랙션이 요구되는 현대 웹 페이지들 → 인터랙션 처리를 위한 동적인 코드는 JavaScript에서만 개발 가능한데, 인터랙션에 의해 값이 변경되는 요소가 있을 경우 `.innerHTML = ${HTML태그로 이것저것 작성}`과 같은 가독성 떨어지는 코드 어느 정도 탈출,,

- 컴포넌트 단위로 ui 재사용 가능 _([3.1. 개념 이해하기] 참고)_

# 3. 리액트 컴포넌트

## 3.1. 개념 이해하기

- Flutter에서 **위젯을 리턴하는 함수**를 만들었던 것과 유사함

- `JSX`로 작성된 마크업을 가진 함수임

- 원래라면 HTML 파일로 작성해야 하는 마크업 코드를 `.jsx` 또는 `.tsx` 파일에서, HTML과 거의 유사한 형태로 작성 (`JSX` 덕분)

- 차이는 하나의 마크업 **문서**를 만드는 대신, 적절한 기능이나 ui별로 **쪼개서** 하나의 function 형태로 작성한다는 점

⇒ 하나의 컴포넌트로 **재사용** 가능해 개발 효율성, 생산성 향상

## 3.2. 정의하기

- 일반적인 JavaScript function과 달리 **대문자로 시작해야 함**

```javascript
export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}
```

-   그 컴포넌트를 사용할 때 일반 HTML 태그와 구분됨

```javascript
export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

- `return` 뒤에는 **반드시** **하나의 부모 태그만** 가져야 함 ⭐️

    - 여러 태그를 사용하려면 `<div>`나 `<>`(empty tag)로 라도 묶어줘야 에러 없음

        - empty tag? (=Fragment)

```javascript
<>
  <h1>Hedy Lamarr's Todos</h1>
  <img 
    src="https://i.imgur.com/yXOvdOSs.jpg" 
    alt="Hedy Lamarr" 
    class="photo"
  />
  <ul>
    ...
  </ul>
</>
```

    - JavaScript의 function에서 여러 개의 값을 리턴할 수 없기 때문임. 하나의 JSX 태그만 리턴하게 해야 한다.

- `return` 뒤에 작성한 태그(`<h1>`, `<img />` 등)가 **한 줄**보다 길어질 경우, `**()**`**로 감싸줄 것**

- 스타일 적용 등을 위해 클래스명을 지정할 때, 일반 HTML에서와 달리 `className=""` 사용

    - `class`가 JavaScript **예약어**이기 때문

    - HTML: `<div class="header"></div>`

    - `jsx`: `<div className="header"></div>`

- 기본적으로 JavaScript라서, 태그 안에 `{}`로 감싸면 JavaScript 문법 사용 가능

    - `let`, `const`로 선언한 JavaScript **변수** 값 사용도 가능하고

        - 예시가 궁금하세요?

```javascript
export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}
```

```javascript
const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}
```

    - `{index === 0 ? '0' : '1'}`과 같은 **조건부 렌더링**도 가능

## 3.3. 사용하기

- JavaScript 문법인 `export`, `import` 활용해 필요한 데서 재사용하며,

_(5. _`_[import](https://www.notion.so/import-export-191ae2c23a73801cba06d799a55bfdd4?pvs=21)_`_[, ](https://www.notion.so/import-export-191ae2c23a73801cba06d799a55bfdd4?pvs=21)_`_[export](https://www.notion.so/import-export-191ae2c23a73801cba06d799a55bfdd4?pvs=21)_`_ 참고)_

- 사용할 땐 `<img />` 태그처럼 `<MyComponent />` 와 같은 셀프 클로징 태그 형태로 사용

# 4. State

- Flutter와 같이, 변수 값이 바뀐다 해서 화면이 재렌더링 되지 않음. 재렌더링이 필요함을 알려줘야 함

- `useState` 훅 사용

```javascript
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  // index는 변수, setIndex는 함수

  function handleClick() {
      // setState와 비슷하쥬?
    setIndex(index + 1);
  }
  
  // 이제 jsx에서 handleClick 함수를 실행하면 재렌더링됨

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}

```

# 5. `import`, `export`

- JavaScript 기본 문법 (React에서만 사용하는 것 X)

- 다른 파일에서 정의한 함수/변수 등을 불러와 사용할 수 있음

- 2가지 방식

1. Default - `default` 키워드, `{}` 사용 X

- `default` 키워드를 포함하여 `export`

- `import` 할 때(마다) 원하는 네이밍으로 불러와 사용 가능

- Named 방식처럼 `{}` 안에 이름 넣어 `import` 작성 시 에러 발생!
-  `Module ‘경로’ has no exported member ‘컴포넌트명’. Did you mean to use ‘import 컴포넌트명 from “경로”' instead?` - `import` 구문 컴포넌트명을 `{}`로 감쌌는지 확인 및 제거하면 해결

```javascript
// Button.js (함수를 정의한 파일)
// 이렇게 작성해 내보냄
export default function Button() {};

// 함수를 불러와 사용할 다른 파일
// 원하는 이름을 맘대로 지어 불러옴
import Button from './Button.js';

// 다른 파일에선 다른 이름으로 사용할 수 있겠쥐요
import CustomButton from './Button.js';

// 코드에서 사용할 땐 임포트 한 이름으로 쓰면 됨
```

2. Named - `default` 키워드 X, `{}` 사용

- `default` 키워드 없이 `export`

- `export`한 파일에서 정의한 이름으로 `import`, `{}` 사용

```javascript
// Button.js
export function Button() {};

// 임포트할 파일
import { Button } from './Button.js';
```

 

# Conclusion

저는 웹 개발을 처음 배울 때 HTML, CSS, JavaScript와 함께 React를 공부했었는데요.

리버스마운틴에 합류한 뒤로는 Flutter로만 개발해서 오랜만에 React를 다시 쓰려니 맞다 이런 게 있었지 하고 새록새록 기억이 나더라고요. 좀 더 깊은 내용들은 이어지는 글들에서 마저 다뤄보도록 하고, 이번 글에서는 이 정도까지만 다뤄볼까 합니다.

특히 우리 팀원들에게 이 글이 도움이 되길 바라요! :)

---

# References

- React 공식 문서
- 

    - [Your First Component](https://react.dev/learn/your-first-component)

    - [Importing and Exporting Components](https://react.dev/learn/importing-and-exporting-components)

    - [Writing Markup with JSX](https://react.dev/learn/writing-markup-with-jsx)

    - [JavaScript in JSX with Curly Braces](https://react.dev/learn/javascript-in-jsx-with-curly-braces)

For the site tree, see the [root Markdown](https://slashpage.com/reversemountain.md).
