본문 바로가기
React & NextJS/NextJS

JSX 이것만 알면 된다: React 와 NextJS 를 위한 UI

by Developer88 2023. 12. 30.
반응형

오늘은 React JS 나 Next JS에서 사용되는 JSX에 대해서 정리해 보도록 하겠습니다.

 

1. JSX

JSX는 Javascript의 extention 인데요.

Javascript 파일안에서,

HTML과 유사한 마크업언어를 사용하도록 해 줍니다.

기존의 HTML지식에, 몇가지 사용 규칙들만 알면 쉽게 익숙해질 수 있습니다.

 

 

2. JSX 사용 규칙들

2-1. 하나의 root attribute 를 return

JSX에서는 괄호 () 안에 HTML 태그를 넣어 UI를 만들어야 합니다.

이때 모든 태그는 하나의 루트 엘리먼트로 감싸져야 해요.

예를 들어, 여러 태그를 <div>와 같은 한 개의 루트 엘리먼트로 묶어서 사용합니다.

 

아래에서는 <main>태그를 루트 엘리먼트로 사용하였네요.

 

const right = (
  <main>
    <div>
      <p>테스트1을 시작합니다</p>
      <p>테스트2를 시작합니다</p>
    </div>
  </main>
);

 

위에서 사용된 main 태그와 같은 루트 엘리먼트를 프래그먼트라고 부를 수 있어요. 

복잡한 내용이 아니라면, <></>와 같은 빈 태그를 사용해도 됩니다.

이런 빈 태그는 단순히 여러 요소들을 하나로 묶는 컨테이너 역할만 해주기 때문이에요.

 

const emptyFragment = (
  <>
    <div>
      <p>Hello World</p>
    </div>
  </>
);

 

아래는 잘못된 사례인데요.

아래와 같이 여러개의 attribute을 넣고 괄호를 닫으면 에러가 발생합니다.

 

const wrong = (
  <>
    <p className="test1">테스트1을 시작합니다</p>
    <p className="test2">테스트2를 시작합니다</p>
  </>
);

 

2-2. tag를 항상 닫기

jsx에서는 tag를 반드시 닫도록 되어 있습니다.

<img>태그 같은 경우에도 반드시 <img/>와 같이 해 주어야 하구요.

<ul>, <ol>, <li> 등도 아래와 같이 </ul>, </ol>, </li> 와 같이 닫아주어야 합니다.


JSX에서는 모든 태그를 반드시 닫아야 해요.

예를 들어, <img> 태그는 <img/>처럼 닫아줘야 합니다.

<ul>, <ol>, <li> 같은 태그들도 각각 </ul>, </ol>, </li>와 같이 끝을 명확하게 닫아 주어야 합니다.

이렇게 태그를 닫는 것은 꼭 지켜야 할 JSX의 규칙 중 하나입니다.

 

<>
  <img 
    src="https://test.jpg" 
    className="photo"
  />
  <ul>
    <li>아이템1</li>
    <li>아이템2</li>
    <li>아이템3</li>
  </ul>
</>

 

2-3. css class 및 id 적용

HTML에서 CSS 클래스를 적용할 때는 class 속성을 사용했습니다.

하지만 JSX에서는 className을 사용해야 합니다.

JSX에서 class 대신 'className'을 사용하는 것을 잊지 마세요. 

 

const right = (
  <main>
    <div className="beauty">
      <p className="test1">hello world</p>
    </div>
  </main>
);

 

 

JSX에서 id 속성을 사용할 때는 HTML과 동일하게 id를 그대로 사용하면 됩니다.

예를 들어, JSX에서 특정 엘리먼트에 ID를 부여하려면 다음과 같이 작성합니다:

 

const App = () => {
  return (
    <div id="myid">ui테스트</div>
  );
};

 

2-4. Javascript부분은 { }를 사용

HTML태그안에서, Javascript 를 사용할 때는,

중괄호 '{ }'를 사용해 주면 됩니다.

 

const add = (a, b) => a + b;
export default function calc() {
  return (
    <div>
      <p>The sum of 1 and 7 is {add(1, 7)}</p>
    </div>
  );
}

 

아래와 같이 객체를 만들어서 접근하는 것도 가능합니다.

 

const person = {
  name: 'kim gun'
};

export default function test() {  
  return (
    <div>
      <h1>Hello, {person.name}!</h1>
    </div>
  );
}

 

 

2-5. Inline style의 표현

JSX에서 CSS 스타일을 직접 적용할 때는 {{ }}를 사용해요. 

바깥쪽 중괄호는 JSX 안에서 JavaScript 코드를 쓰기 위한 것이고, 

안쪽 중괄호는 JavaScript 객체를 의미합니다.

inline 스타일을 적용하려면 아래와 같이 사용해 주면 됩니다.

 

export default function TodoList(){ 
  return (
    <ul style={{ backgroundColor: 'navy', color: 'white' }}>
      <li>아이템1</li>
      <li>아이템2</li>
      <li>아이템3</li>
    </ul>
  );
}

 

한가지 주의할 점은,

css 중에는 중간에 '-'가 들어가는 경우가 있습니다.

이 때는 javascript의 CamelCase를 사용해서 넣어주면 됩니다.

예를 들어, 위에서 사용된 'backgroundColor'는 원래 css에서는 'background-color'가 맞습니다.

하지만, jsx의 규칙에 따라서, camelCase로 변경하여 집어넣었습니다.

 

JSX에서 CSS 스타일을 적용할 때 주의할 점이 있어요. 

CSS에 하이픈(-)이 들어가는 속성들은 JSX에서는 카멜 케이스로 변경해야 합니다.

예를 들어, CSS의 background-color는 JSX에서 backgroundColor로 써야 해요.

이는 JSX에서 JavaScript 객체를 사용해 스타일을 정의하기 때문입니다.

따라서, CSS가 아닌, JavaScript의 네이밍 규칙을 따라야 하는 것 이지요.

 

2-6. EventListener

JSX에서 이벤트 리스너를 사용하는 방법은 간단합니다.

예를 들어, 클릭 이벤트를 처리하려면 onClick 속성을 사용한다고 가정해 보겠습니다.

이벤트 처리 함수를 정의하고, 해당 함수를 onClick 속성에 적용하면 되는데요.

Javascript 함수이므로, 위에서 본 것처럼 { } 를 사용해 주면 됩니다.

 

const handleClick = () => {
  alert('클릭됨!');
};

const App = () => {
  <div>
      <button onClick={handleClick}>확인</button>
  </div>
}

 

2-7. if문

JSX에서는 아래와 같이 return 문 바깥에서, if문을 사용할 수 있습니다.

 

const MyComponent = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <div>환영합니다!</div>;
  } else {
    return <div>로그인 해 주세요.</div>;
  }
}

 

return 문 안에서 삼항연산자(ternary)를 이용해,

조건에 따라 다른 UI를 보여주도록 할 수도 있습니다.

 

const MyComponent = ({ isLoggedIn }) => {
  return (
    <div>
      {isLoggedIn ? <p>환영합니다.!</p> : <p>로그인 해 주세요</p>}
    </div>
  );
}

 

 

아래 예제에서 isHidden이 true이면, 컴포넌트는 null을 반환하여 아무것도 렌더링하지 않습니다.

이 방법은 조건에 따라 특정 컴포넌트를 화면에 표시하지 않고 싶을 때 유용합니다.

null을 반환함으로써 컴포넌트가 전혀 렌더링되지 않도록 하는 것이죠.

 

const ListItem = ({ isHidden, name }) => {
  if (isHidden) return null;
  
  return <li className="item">{name}</li>;
}

 

2-8. 리스트 표현(map)

jsx에서는 Javascript es6의 map 연산자도 사용할 수 있는데요.

다음과 같이 활용해서 리스트를 표현할 수 있습니다.

 

const FruitList = () => {
  const fruits = ['banana', 'apple', 'pineapple'];

  return (
    <div>
      <p>과일의 개수는 {fruits.length}개입니다.</p>
      <ul role="list">
        {fruits.map((fruit) => (
          // Assuming each fruit is unique in this list
          <li key={fruit} role="listitem">{fruit}</li>
        ))}
      </ul>
    </div>
  );
}

 

 

참고로 위에서 사용된 key는 react에서 리스트의 아이템을 트래킹하기 위해 사용하는 것 입니다.

 

html에 보여지는 부분은 아닙니다.

그리고, <li>태그 앞뒤로, 소괄호()로 감싸고 있는 부분이 있는데요.

이것은 가독성을 위한 것으로, 꼭 필수인 부분은 아닙니다.

아래 예제에서는 소괄호()를 사용하지 않았습니다.

 

아래는 공식문서에 나오는 예 입니다.

 

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const chemists = people.filter(person =>
    person.profession === 'chemist'
  );
  const listItems = chemists.map(person =>
    <li>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return <ul>{listItems}</ul>;
}

 

만약 리스트에 아이템이 없어서 아무것도 표시하지 않고자 할 때는, 

리스트의 length를 체크해 길이가 0이면 null을 반환하면 됩니다. 

이 방법을 이용해서 빈 리스트가 화면에 표시되지 않도록 할 수 있습니다.

 

const DynamicList = ({ items }) => {
  if (items.length === 0) {
    return null;
  }

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

 

2-10. 다이나믹한 변수들 사용

아래와 같이 다이나믹하게 변하는 값들을 사용하기 위해서는,

Javascript 의 템플릿 리터럴(Template literals)을 사용해주면 됩니다.

(이전에는 Template String이라는 명칭을 사용했었습니다.)

 

주의할 것은, 따옴표로 감싸주는 것이 아니라,

백틱 (`) 이라고 불리는 것을 사용해서 감싸주는 것이구요.

다이나믹하게 변하는 값을 위한 javascript 표현식은,

아래와 같이 $와 중괄호( $ {expression} ) 로 표기해 주면 됩니다.

 

<img src={`${person.name}.jpg`} alt="description" />

 

3. 정리

JSX는 HTML과 같이 직관적으로 UI를 구성하면서 자바스크립트를 유연하게 섞어 쓸 수 있는 장점이 있어요. 

하지만 코드가 복잡해지거나 가독성이 떨어질 수도 있지요.

HTML과는 조금 다른 규칙이 있어서,

className 사용이나 CSS에서의 카멜 케이스 사용처럼 주의할 점도 있습니다.

JSX를 이해하는데 도움이 되셨으면 좋겠네요.

728x90

댓글