JSX

2022-06-08

  • JSX는 JsvaScript를 확장한 문법으로 React와 함께 사용할 것을 권장합니다. (JsvaScript의 모든 기능 포함)
    • React는 JSX 사용이 필수는 아니지만 UI 관련 작업할 때 시각적으로 더 도움이 됩니다.

const element = <h1>Hello, World!</h1>;

1. 표현식

  • nama이라는 변수를 선언한 후 중괄호( {} )로 감싸 JSX안에 사용
  • user.firstName 또는 formatName(user)등 모두 사용에 유효한 JavaScript 표현식
    • JSX의 중괄호 안에는 유효한 모든 JavaScript 표현식을 넣을 수 있습니다.

 

a. 표현식 : 값을 산출해내는 코드의 조각


// 숫자 표현식
10;
10 + 20;

// 문자 표현식
"hello";
"hello" + "world";

// 논리 표현식
30 > 20;
10 < 20;

// 할당 연산자를 통한 표현식
i = 10;
total = 0;
fruits[1] = "avocado";

// 함수 호출 표현식
sayHello();

 

b. 문장 : 특정한 행동 (JSX에서는 사용 불가)


// 변수 선언
var sum;
var ava;

// if, else 문
if(ex){
  statement 1;
} else{
  statement 2;
}

// for 문
for(let i=0; i < 10; i++){
  console.log(i);
};

  • 컴파일이 끝나게 되면 JSX 표현식이 정규 JavaScript 함수 호출이 되고, JsvaScript 객체로 인식하게 됩니다.

function getGreeting(user){
  if(user){
    return <h1>hello, {formatName(user)} !</h1>
  }
  return <h1>hello, Stranger.</h1>
}

/*
  JSX를 if 및 for loop 안에서 사용하고
  변수에 할당하고, 인자로서 받아들이고
  함수로부터 반환할 수 있다.
*/

 

2. 속성 정의

  • 어트리뷰트에 따옴표(“ “, ‘ ‘)를 이용해 문자열 리터럴 정의
  • 중괄호( { } ) 사용하여 어트리뷰트에 JS 표현식 삽입
    • 어트리뷰트에 JS 표현식을 삽입 할 때 중괄호 주변에 따옴표 사용 X
    • 따옴표 또는 중괄호 중 하나만 사용하고 어트리뷰트에 두 가지를 동시 사용 X
  • 태그가 비어있다면 XML 처럼 < />를 이용해 닫아야 함
  • JSX 태그는 자식을 포함 할 수 있음

// #1
const element = <a href="https://www.reactjs.org">link</a>;

// #2
const element = <img src={user.avatarUrl} />;

/*
  JSX는 HTML보다 JS에 가깝기 때문에 ReactDOM은 HTML 어트리뷰트 이름 대신 camelCase 프로퍼티 규칙 사용
  예시 ) class -> calssName / tabindex -> tabIndex
*/

// #3
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>GooD to see you here.</h2>
  </div>
);

 

3. 객체 표현

  • Babel은 JSX를 React.createElement() 호출로 컴파일 한다.

// #1
const element = (
  <h1 className="greeting">hello, world!</h1>
);

// #2
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'hello, world!'
);

/*React.createElement()는 버그가 없는 코드를 작성하는 데 도움이 되도록 검사를 수행*/

// #3
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'hello, world!'
  }
};

/*React는 이 객체를 읽어 DOM을 구성하고 최신 상태로 유지하는 데 사용*/

 

4. React Element 타입 지정

  • 대문자로 시작하는 JSX태그는 React 컴포넌트를 지정하며, 이 태그들은 같은 이름을 가진 변수들을 직접 참조한다.

 

a. React가 스코프 내에 존재

  • React.createElement를 호출하는 코드로 컴파일되기 때문에 같은 스코프내에 존재해야만 한다.

import React from 'react';
import CustomButton from './CustomButton';

function WarningButton() {
  // return React.createElement(CustomButton, {color: 'red'}, null);
  return <CustomButton color="red" />;
}

/*
  React와 CustomButton은 JS코드에선 직접적으로 사용되지 않지만
  JSX태그로 사용하기 위해 꼭 import 해야 한다.

  <script></script>를 통해 불러왔다면 전역 변수로 존재하기 때문에
  별도로 불러올 필요가 없음.
*/

 

b. JSX 타입을 위한 점 표기법 사용


import React from 'react';

const MyComponents = {
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker() {
  return <MyComponents.DatePicker color="blue" />;
}

 

c. 사용자 정의 컴포넌트는 반드시 대문자로 시작


import React from 'react';

/*잘못된 사용법*/

// 잘못된 사용법으로, 아래는 컴포넌트이므로 대문자화 해야 함.
function hello(props) { // -> function Hello(props) {
  // 올바른 사용법으로, 아래의 <div> 사용법은 유효한 HTML 태그이기 때문에 유효하다.
  return <div>Hello {props.toWhat}</div>;
}

function HelloWorld() {
  // 잘못된 사용법으로, React는 <hello />가 대문자가 아니기 때문에 HTML 태그로 인식.
  return <hello toWhat="World" />; 
}

/*올바른 사용법*/

// 올바른 사용법으로, 아래는 컴포넌트이므로 대문자로 시작해야 한다.
function Hello(props) {
  // 올바른 사용법으로, 아래의 <div> 사용법은 유효한 HTML 태그이기 때문에 유효하다.
  return <div>Hello {props.toWhat}</div>;
}

function HelloWorld() {
  // 올바른 사용법으로, React는 <Hello />가 대문자로 시작하기 때문에 컴포넌트로 인식.
  return <Hello toWhat="World" />;
}

 

d. 실행 중에 타입 선택

  • React element 타입에 일반적인 표현식은 사용할 수 없다.
  • 엘리먼트 타입을 지정할 때 일반적인 표현식을 사용하고자 한다면 대문자로 시작하는 변수에 배정한 후 사용할 수 있다.

import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

/*잘못된 사용법*/
function Story(props) {
  // 잘못된 사용법으로, JSX 타입은 표현식으로 사용할 수 없음.
  return <components[props.storyType] story={props.story} />;
}

/*올바른 사용법*/
function Story(props) {
  // 올바른 사용법으로, 대문자로 시작하는 변수는 JSX 타입으로 사용할 수 있음.
  const SpecificStory = components[props.storyType];
  return <SpecificStory story={props.story} />;
}

 

5. 자식 다루기

  • 여는 태그와 닫는 태그가 있는 JSX 표현에서 두 태그 사이의 내용은 props.children이라는 특수한 prop으로 넘겨진다.

 

a. 문자열 리터럴


  <!-- 
    문자열 리터럴을 넣을 수 있으며 props.children는 문자열이 된다. 
    MyComponent의 props.children은 "Hello world!" 이다.
  -->
<MyComponent>Hello world!</MyComponent>

<!-- HTML은 이스케이프를 처리되지 않으며, 아래의 HTML을 쓰는 방식으로 JSX를 사용할 수 있다. -->
<div>This is valid HTML &amp; JSX at the same time.</div>

  <!-- 
    각 줄의 처음과 끝 공백 제거와 빈 줄 제거
    태그에 붙어있는 개행도 제거되며 문자열 리터럴 중간에 있는 개행은 한 개의 공백으로 배체 된다. 
    전부 똑같이 렌더링된다.
  -->
<div>Hello World</div>

<div>
  Hello World
</div>

<div>
  Hello
  World
</div>

<div>

  Hello World
</div>

 

b. 자식으로 사용


<!-- 중첩된 컴포넌트를 보여줄 때 유용 -->
<MyContainer>
  <MyFirstComponent />
  <MySecondComponent />
</MyContainer>

  <!-- 
    다양한 타입의 자식들을 섞어서 사용
    문자열 리터럴을 JSX 자식과 함께 사용 있다.
   -->
<div>
  Here is a list:
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</div>


/*React 컴포넌트는 element로 이루어진 배열을 반환 할 수 있다.*/
render() {
  // 리스트 아이템들을 추가적인 엘리먼트로 둘러쌀 필요 없습니다!
  return [
    // key 지정을 잊지 마세요 :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

  • JS 표현식을 자식으로 사용


<MyComponent>foo</MyComponent>

<!-- {}에 감싸서 JavaScript 표현식도 자식으로 넘길 수 있다. -->
<MyComponent>{'foo'}</MyComponent>


/*임의의 길이를 가진 JSX 표현식의 배열을 랜더링 할 때 종종 유용하게 사용*/
function Item(props) {
  return <li>{props.message}</li>;
}

function TodoList() {
  const todos = ['finish doc', 'submit pr', 'nag dan to review'];
  return (
    <ul>
      {todos.map((message) => <Item key={message} message={message} />)}
    </ul>
  );
}

/*JavaScript 표현식은 다른 타입의 자식과 같이 쓸 수 있다.*/
function Hello(props) {
  return <div>Hello {props.addressee}!</div>;
}

  • 함수를 자식으로 사용

// 자식 콜백인 numTimes를 호출하여 반복되는 컴포넌트를 생성.
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i++) {
    items.push(props.children(i));
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}
    </Repeat>
  );
}

/*
  JSX에 삽입된 JavaScript 표현식은 문자열, React element 혹은 이들의 배열로 환산된다.
  props.children은 React가 렌더링 할 수 있는 데이터의 형태뿐만 아니라 어떤 형태의 데이터도 넘겨질 수 있다.
  직접 만든 컴포넌트가 있다면 props.children을 통해서 콜백을 넘겨받을 수 있다.
*/

  • boolean, null, undefined는 무시

<!--false, null, undefined와 true는 유효한 자식-->
<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

<!--howHeader가 true일 때 동일하게 <Header />를 렌더하게 된다-->
<div>
  {showHeader && <Header />}
  <Content />
</div>

<!-- 
  0과 같은 “falsy” 값들은 React가 렌더링 한다는 점
  props.messages가 빈 배열일 때 예상과는 다르게 0을 출력
-->
<div>
  {props.messages.length &&
    <MessageList messages={props.messages} />
  }
</div>

<!-- && 앞의 표현식이 언제나 진리값이 되도록 해야한다-->
<div>
  {props.messages.length > 0 &&
    <MessageList messages={props.messages} />
  }
</div>

<!-- false, true, null 또는 undefined와 같은 값들을 출력하고 싶다면 먼저 문자열로 전환 해야한다.-->
<div>
  My JavaScript variable is {String(myVariable)}.
</div>

results matching ""

    No results matching ""

    99 other / uml

    04 react / JSX