[React] 3. JSX, Component

🏃Dekay (JuniorDeveloper)·2021년 9월 20일
0

React

목록 보기
3/13
post-thumbnail

1. JSX ✔

  • JSX(Javascript Syntax Extension)은 말 그대로 자바스크립트의 확장 문법으로 XML과 매우 비슷하다.
  • JSX 형식으로 작성된 코드는 브라우저에서 실행되기 전 코드가 번들링되는 과정에서 Babel을 사용하여 일반적인 자바스크립트 형태의 코드로 변환된다.

1.1 JSX 장점

  • HTML 태그를 그대로 사용하기 때문에 보다 쉽게 작성할 수 있고 가독성 또한 높다.
  • HTML 태그와 앞으로 만들 컴포넌트 그리고 자바스크립트JSX에서 작성할 수 있다.

1.2 JSX 문법

  • JSX를 올바르게 사용하려면 몇 가지 규칙을 준수해야 한다.

1.2.1 감싸인 요소

  • 컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다.
import React from 'react';


function App() {
  return (
    <h1>리액트</h1>
    <h2>작동 테스트</h2>
  )
}

export default App;
  • 위와 같은 형태의 코드는 제대로 동작하지 않는다.
  • 요소 여러 개가 부모 요소 하나에 감싸져 있지 않기 때문에 다음과 같이 수정해야 한다.
function App() {
  return (
    <div>
      <h1>리액트</h1>
      <h2>작동 테스트</h2>
    </div>
  );
}
  • 위와 같이 하나의 요소로 꼭 감싸 주는 이유는 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 하는 규칙이 있다.
  • 추가적으로, div 요소를 사용하고 싶지 않은 경우에는 React v16 이상 부터 도입된 Fregment라는 기능을 사용하면 된다.

1.2.2 자바스크립트 표현

  • JSX 안에서 자바스크립트 표현식을 쓸 수 있는데, JSX 내부에서 코드를 { }로 감싸면 된다.
function App() {
  const name = '박대경';
  return (
    <div>
      <h1>{name} 안녕</h1>
      <h2>작동 테스트</h2>
    </div>
  );
}

1.2.3 If문 대신 조건부 연산자

  • JSX 내부의 자바스크립트 표현식에서 If 문을 사용할 수 없다.
  • 하지만, 조건에 따라 내용을 렌더링해야 할 때는 JSX 밖에서 if 문을 사용하여 사전에 값을 설정하거나, { } 안에 조건부 연산자를 사용하면 된다.
function App() {
  const name = '박대경';
  return (
    <div>
      {name === '박대경' ? (
        <h1>박대경 입니다.</h1>
      ) : (
        <h2>박대경이 아닙니다.</h2>
      )}
    </div>
  );
}

1.2.4 AND 연산자(&&)를 사용한 조건부 렌더링

  • 개발하다 보면 특정 조건을 만족할 때 내용을 보여 주고, 그렇지 않아야 할 상황이 올 수 있다.
// 👉 방법 1
function App() {
  const name = '박대경';
  return <div>{name === '박대경' ? <h1>박대경 입니다.</h1> : null}</div>
}

// 👉 방법 2
function App() {
  const name = '박대경';
  return <div>{name === '박대경' && <h1>박대경 입니다.</h1>}</div>
}
  • 방법 2&& 연산자로 조건부 렌더링이 가능한 이유는 리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문이다.

1.2.5 undefined를 렌더링하지 않기

  • 리액트 컴포넌트에서는 함수에서 undefined만 반환하여 렌더링 하는 상황을 만들면 안된다.
    예를들어, 다음과 같은 코드는 오류를 발생한다.
function App() {
  const name = undefined;
  return name;
}

// 👉 결과: ×
Error: App(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
  • 어떤 값이 undefined일 가능성이 있다면 OR(||) 연산자를 사용하여 해당 값이 undefined일 때 사용할 값을 지정할 수 있어서 오류를 방지할 수 있다.
function App() {
  const name = undefined;
  return name || 'undefined';
}
  • 위와 같은 코드를 보면 name 값이 undefined일 때 보여주고 싶은 문구나 기본 값을 보여주고 싶을 때 OR(||) 연산자를 사용하면 될 것 같다.

1.2.6 인라인 스타일링

  • 리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태가 아닌 객체 형태로 넣어야 한다.
  • 스타일 이름 중에서 background-color처럼 - 문자가 포함되는 이름이 있는데, -를 지우고 카멜 표기법으로 작성해야 한다.
    즉, backgroundColor로 작성
function App() {
  const name = '박대경';
  const style = {
    // 모든 표기는 카멜 표기법으로 작성
    backgroundColor: 'black',
    color: 'aqua',
    fontSize: '24px',
    fontWeight: 'bold',
    padding: 16 // 단위 생략하면 px로 자동 지정된다.
  }
  return <div style={style}>{name}</div>
}
  • 만약 style 객체를 미리 선언하고 divstyle 값으로 지정했는데, 미리 선언하지 않고 style 값을 지정하고 싶다면 div style=({...스타일 선언... })과 같이 작성하면 된다.

1.2.7 class 대신 className

  • 일반 HTML에서 css 클래스를 사용할 때는 <div class="myclass"></div>와 같이 class라는 속성을 설정한다.
  • 하지만, JSX에서는 class가 아닌 className으로 설정 해야한다.
.react {
  background: aqua;
  color: black;
  font-size: 48px;
  font-weight: bold;
  padding: 16px;
}
  • src/App.css 파일에 위와 같은 코드를 작성한 후 App.js 파일에서 상단에 App.css를 불러온 뒤 div 요소에 className 값을 지정하면 된다.
import React from 'react';
import './App.css';


function App() {
  const name = '박대경';
  return <div className="react">{name}</div>
}

export default App;
  • 만약 실수로 classNameclass로 해도 리액트 v16 이상은 자동으로 변환시켜 주고 개발자 도구console 탭에 경고만 출력한다.

1.2.8 꼭 닫아야 하는 태그

  • HTML 코드는 <input></input> 요소를 닫지 않고 열기만 하여도 문제없이 작동하지만, JSX에서는 태그를 닫지 않으면 오류가 발생한다.
  • 또한, 태그 사이에 별도의 내용이 들어가지 않는 경우에는 <input />로 사용해도 되며 이를 self-closing 태그라고 한다.

1.2.9 주석

  • JSX 안에서 주석을 작성하는 방법이 자바스크립트 주석과 조금 다르다.
function App() {
  const name = '박대경';
  return (
    <>
      {/* 주석 사용법 */}
      <div 
        className="react" // 시작 태그를 여러 줄로 작성하면 주석 사용 가능
      >
        {name}
      </div>
      // 그러나 이런 주석이나
      /* 이런 주석은 주석 처리가 되지 않는다. */
    </>
  );
}

JSXHTML하고 비슷해 보이지만 또 조금씩 틀린 부분이 있어서 조금 햇갈린다..😂
그 만큼 많이 써보면서 얼른 적응해야지..


2. Component 🧐

  • 컴포넌트는 재사용이 가능한 UI 구성 단위이다.
    즉, 각각의 독립된 모듈
  • 예를 들어, 아래의 그림과 같이 ObjectTop, Right, Left, Bottom 요소들을 레고 블럭처럼 이미 만들어진 컴포넌트를 조합하여 화면을 구성할 수 있다.

2.1 Component 장점 👍

  • 재사용하기 쉽기 때문에 유지보수 비용을 절약할 수 있다.
    즉, 코드를 유지보수 하기 쉽다.
  • 페이지가 어떻게 구성되어 있는지 한 눈에 파악하기 쉽다.
  • 컴포넌트는 다른 컴포넌트를 포함할 수 있다.
    부모 컴포넌트 - 자식 컴포넌트

2.2 클래스형, 함수형 컴포넌트

  • 컴포넌트를 선언하는 방식은 함수형 컴포넌트클래스형 컴포넌트 두 가지가 있다.

2.2.1 클래스형 컴포넌트

  • 클래스형 컴포넌트의 사용방법은 아래 코드와 같다.
import React from 'react';
import { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    const name = '박대경';
    return <div className="react">{name}</div>;
  }
}

export default App;
  • 위의 코드와 같이 클래스형 컴포넌트는 반드시 render 함수가 있어야 하고, 그 안에 보여줄 JSX를 반환한다.

2.2.2 함수형 컴포넌트

  • 함수형 컴포넌트는 이전에 사용 했던 방법들이 함수형 컴포넌트이다.
import React from 'react';
import './App.css';

function App() {
  const name = '박대경';
  return <div className="react">{name}</div>;
}

export default App;
  • 함수형 컴포넌트 보다 클래스형 컴포넌트가 선언하기도 쉽고 메모리 자원도 덜 사용하기도 한다.
  • 또한, 클래스형 컴포넌트함수형 컴포넌트의 차이점은 클래스형 컴포넌트state 기능, 라이프사이클 기능을 사용할 수 있는 점과, 임의 메소드를 정의할 수 있다는 것이다.
    * 하지만, 리액트 v16.8 업데이트 이후 Hooks 기능으로 해결되었다.

2.3 Component 생성

  • 컴포넌트 생성 과장은 세 가지로 나눌 수 있다.
  • 파일 만들기 -> 코드 작성하기 -> 모듈 내보내기 및 불러오기

2.3.1 src 디렉터리에 MyComponent.js 파일 생성 및 코드작성

  • src 디렉터리에 MyComponent.js 파일 생성
  • 컴포넌트를 만들기 위해서는 반드시 컴포넌트 코드를 선언해야 한다.
import React from "react";

const MyComponent = () => {
    return <div>첫 번째 컴포넌트</div>;
};

export default MyComponent;
  • 위와 같은 코드는 함수형 컴포넌트로, function 키워드 대신 애로우 함수를 사용한 코드이다.

2.3.2 모듈 내보내기 및 불러오기

2.3.2.1 모듈 내보내기

  • 작성한 컴포넌트에서 맨 아래 코드는 다른 파일에서 이 파일(src/MyComponent.js)import할 때, 위에서 선언한 MyComponent 클래스를 불러오도록 설정하는 코드이다.
export default MyComponent;

2.3.2.2 모듈 불러오기

  • 아래의 코드에서 import 구문을 사용하는 두 번째 줄이 방금 만든 MyComponent 컴포넌트를 불러오는 코드이다.
import React from 'react';
import MyComponent from './MyComponent';


const App = () => {
  return <MyComponent />;
}

export default App;

근데 생각해보니까 왜 App.js에 있는 화면이 메인으로 띄워질까??🤔
리액트번들러를 활용한다고 이해했었다. 특히 CRA를 활용하여 WebpackBabel의 설정을 하지 않고 자동으로 구축해줘서 몰랐는데 node_modules에 가보니 Webpack이 알아서 설치가 되어있었다.

  • Webpack은 가장 처음으로 읽어들이는 entry point 부터 시작해서 필요한 모듈을 다 불러온 뒤 번들링하여 한 파일로 합쳐서 bundle.js에 저장하는 역할을 한다.
  • Webpack 설정 파일에서 확인한 결과 entry pointindex.js로 정의 되어있었다.
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
  • index.js를 확인한 결과 App.js의 요소를 그리도록 작성이 되어있다.
  • 여기를 수정하면 첫 화면에 원하는 컴포넌트를 출력할 수 있는 것 같다.

end

profile
Believe you can & you're half way there 🙏

0개의 댓글