본문 바로가기
Udemy - React완벽가이드

JSX

by Hanachoi 2023. 2. 3.

#JSX 소개

  • JSX는 자바스크립트 XML을 의미한다. 결국 html을 XML이라고 할 수 있다
  • 뒤에서 변환되고 있는 이 자바스크립트 코드들을 크롬 개발자도구를 켜서 살펴 볼 수 있다. 
  • sources 부분을 보면 여러가지 파일들을 볼 수 있고 복잡해보이는 코드들이 보인다. 
  • 얘네들은 변환된 코드다. 우리의 코드 뿐만 아니라 전체 리액트 라이브러리 소스 코드와 전체 리액트 돔 라이브러리 소스 코드를 포함한다.

  • JSX는 기본적으로 우리가 사용하는 언어는 아니지만 브라우저에 맞게 변환된다. 

 

 

#리액트 작동방식

  • 기본적으로 App.js 파일을 보면 function App() 이 안에 들어있다. 
  • 이건 자체 html요소를 구축한 것이다. 바로 이게 컴포넌트! 컴포넌트는 기본적으로 자체 html 요소일 뿐이다.
  • 우리의 궁극적인 목표는 결국  return 부분의  html 코드를 반환하는 것이다.

  • 기본적으로 모던자바스크립트에서는 새로운 <p> 태그를 넣고 싶을때 코드가 상당히 길어진다.
  • 아래의 자바스크립트 코드는 명령형 접근 방식을 따르고 있다. 우리가 직접 자바스크립트와 브라우저가 단계별로 무엇을 해야하는지 일일히 지시해줘야 한다.
const para = document.createElement('p')
para.textContent = "this is also visible"
document.getElementById('root').append(para)
  • 리액트로 작업하면 그냥 최종상태를 정의하기만 하면 리액트는 이런 파일들을 불러오기 위해 뒷단에 생성을 한다. 

 

#첫 번째 사용자 지정 컴포넌트 만들기

  • 우리는 컴포넌트당 하나의 파일을 만들어서 저장을 할 것이다. 리액트는 컴포넌트의 집합체라 이렇게 하면 엄청나게 많은 파일들이 생기겠지만 이건 지극히 정상이다
  • App.js 파일도 하나의 컴포넌트지만 special 컴포넌트로 Role in the application 이다. it is so-called root component. index.js 파일에서 랜더링 되는 주요 구성요소임을 의미한다.
  • 모든 컴포넌트들은 App.js 파일안에 또는 다른 컴포넌트 안에 중첩될 것이다.
  • 리액트로 작업할 때, 우리는 근본적으로 컴포넌트 트리를 구성한다. 
  • 맨 위에 가장 중요한 <App />컴포넌트가 있고, 그 아래에는 어떤 종류의 사용자 지정 html 을 가질 수 있다. 이런 컴포넌트들은 유저인터페이스의 조각들이 될 것이다.
  • 큰 작업일 수록 당연히 컴포넌트 트리도 커지게 된다.

  • 오직 가 장 상단에 있는 <App />컴포넌트만이 html 페이지에 직접 렌더링 된다. Rendered into signle HTML page

 

  • 리액트에서 파일을 만들때 무슨 이름이든지 설정할 수 있지만, 몇가지 conventional 들이 있다.
    • 대문자로 시작한다. 
    • camelCase를 사용한다.
    • 파일이름을 보고 어떤 로직이 html 파일 안에 있을지 알 수 있도록 설정한다.
  • 리액트에서 컴포넌트를 만들 때 한가지 기억해야 할 가장 중요한 포인트는 컴포넌트는 자바스크립트 함수라는 것!!
  • 기본적인 함수의 틀 안에 JSX로 씌여진 HTML 코드들이 return되어야 한다.
  • 여러개의 함수들이 컴포넌트로 만들어 지지만, 컴포넌트가 화면에 무엇을 렌더링 하는지에 따라 인터페이스가 달라지게 되는 것이다. 
  • 이렇게 ExpenseItem.js라는 컴포넌트를 만들게 되면 우리는 꼭 export를 해줘서 다른 파일에서 사용할 수 있도록 해줘야 한다.

  • 그리고 App.js 파일에서 import를 해줘야 사용 가능하다

  • 이렇게 컴포넌트를 import 해오면 우린 이제 html요소처럼 사용이 가능하다.
  • 위 이미지에서 <p></p> 태그 대신 방금 우리가 만든 컴포넌트를 넣을 수 있다
  • 그냥 html 코드와 다른점은 대문자로 시작한다는 것. 대문자로 시작하는 컴포넌트를 만들어야 리액트에서 컴포넌트를 감지 할 수 있다. 

  • 리액트는 소문자로 시작하는 태그는 html로 인식해 내장요소로 찾을 것이고, 대문자로 시작하는 요소는 사용자 정의태그로 인지한다. 
  • 항상 이순서대로 하면 된다! html 태그를 형성하는 함수를 만들고 export 한다. 그리고 사용하고 싶은 파일에서 import 해준다. 그리고 그 import 된 파일안에서는 JSX 문법으로, 대문자로 시작하는 html 요소를 써준다. 

 

#더 복잡한 JSX 코드 작성

  • 위에서 만든 <ExpenseItem> 컴포넌트에  더 많은 요소들을 추가하고 싶다면?
  • 코드를 작성할 때는 아래의 예시처럼 한 줄에 모두 표시를 하면 안된다. 오류가 날 뿐 만 아니라, 가독성도 떨어지게 된다. 

  • 반환하는 문장마다 혹은 JSX 코드조각마다 반드시 한 개의 루트요소를 가지게 된다. 위 처럼 코드가 작성되면 2개의 루트요소가 들어가게 되는 것이다.  
  • 이 문제를 해결하는 가장 쉬운 방법은 또 다른 하나의 <div>로 전체를 감싸주는것이다. 

  • 가독성의 향상을 위해서 모든 태그를 ()로 묶어서 간단하게 자바스크립트에게 이것은 하나의 한 문장이라고 신호를 보내 줄 수 있다. 
  • <Shift> + <Alt> + F  단축기를 이용해 Auto format shortcut을 사용하는 것이다. 자동으로 코드가 깔끔하게 정리된다. 

  • 이렇게 코드를 정리해서 봤을 때, 이제 가장 큰 <div>태그가 루트요소가 되는걸 볼 수있다. JSX 문법에서는 반드시 이렇게 하나의 루트요소만이 존재해야 한다. 
  • 이렇게 큰 하나의 <div> 안에는 여러개의 요소가 있을 수 있다.  
  • 이렇게 만든 컴포넌트 안에서 앱의 구성 요소를 바꿔 줄 수 있는 것이다.

 

#기본 CSS 스타일 추가

  • CSS에 관해서는 특별히 다른 점은 없고 그냥 기존의 CSS파일을 이용하면된다.
  • 우리는 컴포넌트들을 담아놓는 폴더를 만들었는데, JS 파일 옆에 그냥 CSS 파일을 만들어서 추가해줘도 상관없다.
  • 하지만 한 가지 중요한 점은 js 파일에서 css파일을 import 해줘야 한다는 점!
  • 아래의 이미지를 보면 components 폴더에 ExpenseItem.css 파일을 만드록 ExpenseItem.js 파일에서 css 파일을 import 해줬다. 

  • css 파일에는 이미 디자인이 들어가있고 그 각각의 디자인마다 class가 붙어있다. 
  • 리액트에서 클래스에 이름을 줄때 우리는 className을 사용해서 이름을 붙여준다.  class는 이미 자바스크립트에서 예약된 언어이기 때문이다.
  • 아래의 이미지처럼 className을 각각 부여해주면 css 디자인이 입혀진다.

 

 

#JSX에서 동적데이터 출력 및 표현식 작업하기

  • 위의 예시에서는 hard coding 이 되어있기 때문에 하나의 값만이 컴포넌트에 들어가 있다. 우리는 여기에 비용도 추가하고 여러가지 비용들을 추가해서 넣고 싶다. 결국 이 것이 컴포넌트 뒤에 있는 핵심 아이디어 중의 하나이다.
  • 컴포넌트는 걱정되는 부분들을 나눠 놓는 것 뿐만 아니라, 재사용성(Reusability)의 문제이기도 하다. 

  • 우리는 코드가 정의되면 재사용되길 바라지만, 현재까지 만든 코드로는 재사용이 불가능하다. 어떻게 하면 될까?
  • 일단 처음으로 우리가 하드코딩한 부분을 수정해야한다. 우리는 하드코딩을 하지 않고 어디선가 받아들여온 값을 통해서 이 html 파일에 값을 넣어줘야 한다.
  • 이렇게 동적인 데이터는 어떻게 추가 할 수 있을까? 리액트는 html, css, js 의 구성으로 이루어져 있다. 컴포넌트는 자바스크립트의 함수이고 우리는 이 함수를 반환하기 전에 자바스크립트 코드를 추가해 줄 수 있다.
  • 아래의 이미지처럼 return() 전에 자바스크립트 코드로 변수를 설정해준다. html 에 직접 하드코딩해서 값을 넣기보다는 동적으로 만들기 위해서 이렇게 변수에 값을 넣어준다. 

  • 이렇게 변수를 만들어 줬으면 우리는 return() 부분으로 넘어가서 JSX 코드 안에 js 코드를 넣어주면 된다.
  • 자바스크립트 코드를 쓰기 위해서는 {}를 사용한다.
  • {}안에는 1+1 혹은 Math.random()과 같은 자바스크립트 코드를 작성할 수도 있고 위에서 만든 변수들을 넣어줄 수도 있다. 이렇게 되면 동적인 코드가 만들어 지는 것이다. 

  • 한가지 여기서 주의할 점은 날짜를 위해 만든 expenseDate는 자바스크립트의 date객체를 사용한것이라 그대로 문자가 출력되지 않는다. 그래서 {expenseDate.toISOString()}을 추가해서 넣어준다. 

 

#props를 통해 데이터 전달하기

  • 어떻게 이 컴포넌트들을 재사용할 수 있을까? 
  • 기본적으로 App.js 파일에서 <ExpenseItem></ExpenseItem>을 여러번 사용하면 컴포넌트의 재사용이 가능하긴 하다. 하지만 내용은 그대로인 부분이니 제대로 된 재사용이라고는 할 수 없다.
  • 내용이 그대로인 이유는 이 데이터가 컴포넌트에 고정되어 있기 때문이다.
  • 자바스크립트의 개념으로 잠시 돌아가보자. 자바스크립트에서 함수를 만들면 파라미터를 통해서 여러가지 데이터를 가져와서 사용이 가능했고 입력값에 따라 일반적으로 다른 결과값을 출력할 수 있다. 하지만 여전히 같은 함수가 호출된다. 
  • 리액트에서도 기본적으로 비슷한 개념이 있어서 재사용 할 수 있는 컴포넌트를 만들 수 있다.  매개변수를 사용하거나 리액트의 props라는 개념을 사용해서 가능하다. 

  • COurseGoalItem 컴포넌트에서 그냥 goalItem의 값을 가져와서 사용 할 수는 없다. 다른 컴포넌트에 속해있는 애들이기 때문이다. 그래서 바로 값을 사용하는게 아니라 props를 사용해서 사용자 지정 컴포넌트에 데이터를 추가할 수 있다.
  • 우리는 지금 사용자 정의 html 태그들을 만들어서 사용하고 있다. 리액트에서 우리만의 사용자 지정 컴포넌트도 속성을 가질 수 있게 된 것이다.
  • 리액트에서는 attribute대신 props라는 용어를 쓴다. props는 properties의 준말이다.

 

 

  • 위의 예시에서처럼 Expensetem.js 대신 App.js에 사용하고자 하는 값들이 저장되어야 한다.
  • App.js 파일엣 return()부분 전에도 변수를 넣어줄 수 있는데, 여기에 배열/ 또다시 객체의 형태로 값을 저장할 수 있다.
  • 여러개의 값을 저장 할 수 있다.

  • 이렇게 들어온 값들은 각각의 <ExpenseItem></ExpenseItem>에 넣어주면 된다. 이 뜻은 <ExpenseItem>을 외부로부터 설정할 수 있도록 하고 싶다는 뜻이다.
  • 데이터는 <ExpenseItem> 컴포넌트 안에 저장되는 것이 아니라 대신 밖에서 받아주어야 한다. 이작업은 props의 컨셉으로 작동한다.
  • 값을 할당할때는 {}를 사용해서 할당할 수 있다. 

  • .(점)뒤에 나오는 프로퍼티의 이름은 위의 객체에서의 이름과 동일하게 일치해야한다. 
  • 여기서 <shift>+<Alt>+F를 눌러서 서식정리를 해줄 수 있다. 

  • 하지만! 여기까지 작업을 해도 내용은 변함이 없다. 아직 절반밖에 처리가 안됬기 때문이다.
  • 이 속성들의 이름은 우리에게 달려있다. 마음대로 정해도 되지만 어느정도 값을 알아볼 수 있도록 이름을 정하는게 좋다.
  • 또한 <ExpenseItem.js>파일에서 받아들이는 속성값으로 작업을 해줘야 작동이 정상적으로 된다. 
  • 그럼 이 파일에서는 어떻게 값을 전달할 수 있을까? 파라미터를 사용하면 된다. 하지만 리액트에서는 여러가지의 매개변수를 전달하는 대신, 하나의 매개변수를 사용한다. 그게 바로 props!!
  • props는 여러가지 이름을 정할 수 있지만 대체적으로 props라는 이름을 그대로 사용한다.
  • <ExpenseItem.js>파일에서는 props로 매개변수를 받아주고, 이제 우리가 설정한 title, amount, date 등의 값들은 props로 접근해서 사용이 가능해진다.

  • ExpenseItme.js 파일에서 기존에 가지고 있던 세 개의 변수는 이제 필요가 없어졌으니 지워도 된다. 대신 props를 통해 받아온 title, amount, date를 통해서 접근하게 되는것이다.
  • 이 뜻은 이 컴포넌트 밖에서 데이터를 얻어온다는 의미이다. 그렇기 때문에 ExpenseItem 컴포넌트 안에서 정의를 내릴 필요가 없다는 뜻이다.  대신 App.js에 정의해서 ExpenseItem에 전달을 해준 것 
  • 이런식으로 컴포넌트 사이에서 데이터를 전달할 수 있게 된다.

'Udemy - React완벽가이드' 카테고리의 다른 글

리액트 state 및 이벤트 다루기  (0) 2023.02.18
컴포넌트 구성 분할  (0) 2023.02.13
Basic of React  (1) 2023.01.30
Javascript 리마인드  (0) 2023.01.29
Intro React  (0) 2023.01.26

댓글