[hello-react] Day03 - 리액트 컴포넌트와 JSX

연도리·2022년 4월 27일
0

reactStudy

목록 보기
1/5

참고 글 : https://velopert.com/3626

리액트를 사용하는 이유

리액트를 사용하면 웹 애플리케이션에서 사용하는 유저 인터페이스를 재사용 가능한 컴포넌트로 분리해 작성하여, 프로젝트의 유지보수성을 우수하게 해준다.
(위 소스에서 컴포넌트에 해당하는 코드는 App.js)

컴포넌트

컴포넌트를 만드는 방법은 두 가지가 있다. 하나는 클래스를 통해서 만드는 방법과 나머지는 함수를 통하여 만드는 것이다.

class App extends Component{
	...
}

클래스 형태로 만들어진 컴포넌트에는 꼭 render 함수 가 있어야 한다. 그리고 그 내부에서는 JSX를 return 해주어야 한다. 아래에 있는 HTML같은 코드가 바로 JSX 이다.

render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }

여기서 작성한 컴포넌트를 다른 곳에서 불러와서 사용할 수 있도록 내보내기를 해주어야 한다.

export default App;

다른 곳에서 컴포넌트를 불러올때는 import 를 사용해서 불러온다.

import App from './App';

JSX

얼핏 보기에는 HTML같지만 아니다. 자바스크립트이다.
리액트 개발을 쉽게 하기 위해 HTML과 비슷한 문법으로 작성하면 이를 React.createElement를 사용하는 자바스크립트 형태로 변환해주는 것이다.
XML 형태의 코드를 자바스크립트로 변환해야 하기 때문에, JSX를 제대로 사용하려면 몇 가지 규칙을 준수해줘야 한다.

꼭 닫혀야 하는 태그

html에서 input이나 br 태그 작성시 태그를 안 닫을 때도 있는데 리액트에서 똑같이 하면 이런 오류를 겪게 된다.

잘못된 예시


class App extends Component{
  render(){
    return (
      <div>
        <input type="text"> //error!
      </div>
    )
  }
}

export default App;

올바른 예시


class App extends Component{
  render(){
    return (
      <div>
        <input type="text"></input>
      </div>
    )
  }
}

export default App;

감싸져 있는 엘리먼트

두 개 이상의 엘리먼트는 무조건 하나의 엘리먼트로 감싸져 있어야 한다.

잘못된 예시

import React, { Component } from 'react';

class App extends Component{
  render(){
    return (
      <div>
        Hello
      </div>
      <div> //error!
        Bye
      </div>
    );
  }
}

export default App;

올바른 예시


class App extends Component{
  render(){
    return (
      <div>
        <div>
          Hello
        </div>
        <div>
          Bye
        </div>
      </div>
    );
  }
}

export default App;

Fragment

간단하게 새로운 div를 사용하여 감쌀 수 있지만, 상황이 여의치 않을 수 있다. 예를 들면 스타일 관련 설정을 하면서 코드가 꼬이거나, table 관련 태그를 작성할 때 번거로울 수 있다.
그러한 상황에 Fragment라는 것을 사용하면 된다.(v16.2에 도입)

import React, { Component, Fragment } from 'react';

class App extends Component{
  render(){
    return (
      <Fragment>
        <div>
          Hello
        </div>
        <div>
          Bye
        </div>
      </Fragment>
    );
  }
}

export default App;

JSX 안에 자바스크립트 값 사용하기

JSX 내부에서 자바스크립트 값을 사용할 때

import React, { Component } from 'react';

class App extends Component{
  render(){
    const name = 'react';
    return (
      <div>
        hello {name}~!
      </div>

    );
  }
}

export default App;

const, let, var의 차이

const ES6에 도입된 키워드로서, 한 번 선언하고 바뀌지 않는 값을 설정할 때 사용
let const와 비슷하나 바뀌게 될 수 있는 값을 설정할 때 사용

기존 자바스크립트의 var와 비슷하다고 생각할 수 있으나, 작동 방식에 있어서 scope가 다름

var scope가 함수 단위 (ES6에서 쓸 일 없음)
const, let scope가 블록 단위

function foo() {
  var a = 'hello';
  if (true) {
    var a = 'bye';
    console.log(a); // bye
  }
  console.log(a); // bye
}

function foo() {
  let a = 'hello';
  if (true) {
    let a = 'bye';
    console.log(a); // bye
  }
  console.log(a); // hello
}

조건부 렌더링

JSX 내부에서 조건부 렌더링을 할 때는 보통 삼항 연산자를 사용하거나 AND 연산자를 사용한다. IF문을 사용할 수는 없지만 사용하려면 IIFE(즉시실행함수표현)을 사용해야 한다.

삼항연산자

import React, { Component } from 'react';

class App extends Component{
  render(){
    return (
      <div>
        {
          1 + 1 === 2
            ? (<div>맞아요!</div>)
            : (<div>틀려요!</div>)
        }
      </div>

    );
  }
}

export default App;

AND 연산자

삼항연산자는 TRUE일 때와 FALSE일 때 다른 것을 보여주고 싶을 때 사용하고, AND 연산자의 경우 단순히 조건이 TRUE일 때만 보여주고 FALSE일 경우 아무것도 보여주지 않을 때 사용한다.

import React, { Component } from 'react';

class App extends Component{
  render(){
    return (
      <div>
        {
          1 + 1 === 2
            && (<div>맞아요</div>)
        }
      </div>

    );
  }
}

export default App;

IIFE

대부분의 상황엔 위의 방식으로 해결할 수 있지만 가끔씩 좀 복잡한 조건을 작성해야 할 때도 있다. 그러한 조건들은 웬만하면 JSX 밖에서 로직을 작성하는 것이 좋다. 꼭 JSX 내부에서 작성해야 한다면, 이렇게 IIFE를 사용한다.

import React, { Component } from 'react';

class App extends Component{
  render(){
    const value = 1;
    return (
      <div>
        {
          (function(){
            if(value === 1) return (<div>하나</div>);
            if(value === 2) return (<div></div>);
            if(value === 3) return (<div></div>);
          })()
        }
      </div>

    );
  }
}

export default App;

If문 대신에 switch문을 사용해도 상관 없고, 위 코드는 다음과 같이 화살표 함수를 이용하여 쓸 수도 있다.
(화살표함수 this, arguments, super 개념이 없는 익명 함수 =>참고)

(() => {
       if(value === 1) return (<div>하나</div>);
       if(value === 2) return (<div></div>);
       if(value === 3) return (<div></div>);
})()

style과 className

import React, { Component } from 'react';

class App extends Component{
  render(){
    const style = {
      backgroundColor: 'black',
      padding : '16px',
      color : 'white',
      fontSize : '12px'
    };
    return (
      <div style = {style}>
        hi there
      </div>

    );
  }
}

export default App;

html에서는 그냥 텍스트 형태로 ="backgroundColor: black; padding: 16px; ..." 이런 식으로 작성했었지만, 리액트에서는 객체 형태로 작성해야 한다.
클래스를 설정할 때에도 html에서는 <div class="hello"> 라고 작성하지만, 리액트 컴포넌트에서는 class 대신에 className을 사용한다.

App.css

.App {
  background: black;
  color: aqua;
  font-size: 36px;
  padding: 1rem;
  font-weight: 600;
}

App.js

import React, { Component } from 'react';
import './App.css'

class App extends Component{
  render(){
    return (
      <div className="App">
        리액트
      </div>

    );
  }
}

export default App;

주석달기

주석은 {* ...*} 사이에 넣거나, 태그 사이에 넣을 수도 있습니다.

import React, { Component } from 'react';
import './App.css'

class App extends Component{
  render(){
    return (
      <div className="App">
        {/*주석은 이렇게 */}
        <h1 
        //태그 사이에 
        >리액트</h1>
      </div>

    );
  }
}

export default App;
profile
아장아장 초보 개발자

0개의 댓글