먼저 리액트 코드를 이해해 봅시다 !!!
import logo from "./logo.svg";
import "./App.css";
src/App.js 파일을 열면 볼 수 있다. 여기서 import 구문이 사용됐다. 이는 특정 파일을 불러오는 것을 의미한다. 리액트로 만든 프로젝트의 자바스크립트 파일에서는 import를 사용하여 다른 파일들을 불러와 사용할 수 있다.
여기서!!! 번들링과 웹팩을 집고 넘어가야하지만 난 솔직히 잘 모르겠다 ㅠㅠ 번들링과 웹팩 일단 이거라도 보면서 천천히 이해해보자 ..
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
처음 리액트를 실행하고 App.js 파일을 보면 이러한 코드를 볼 수 있다. 이 코드는 App이라는 컴포넌트를 만들어줍니다. function 키워드를 사용하여 컴포넌트를 만들었죠? 이러한 컴포넌트를 함수 컴포넌트라고 부릅니다.
컴포넌트란?
컴포넌트(Component)란 프로그래밍에 있어 재사용이 가능한 각각의 독립된 모듈을 뜻한다.
그림에서 확인 할 수 있듯이 컴포넌트 기반 프로그래밍을 하면 마치 레고 블록처럼 이미 만들어진 컴포넌들을 조합하여 화면을 구성할 수 있다.
웹 컴포넌트는 이러한 컴포넌트 기반 프로그래밍을 웹에서도 적용할 수 있도록 W3C에서 새로 정한 규격이다. 웹 표준을 기반으로 구축되었으며, 최신 부라우저 및 모든 JavaScript 라이브러리, 프레임워크에서도 사용할 수 있다.
따라서 웹 컴포넌트를 이용하여 코드를 작성하면 Vue.js 나 React.js 와 같은 라이브러리, 프레임워크에 의존하지 않고 상호 운용이 가능하게끔 작성할 수 있다.
프로젝트에서 컴포넌트를 렌더링하면(렌더링이란 '보여준다'는 것을 의미한다) 함수에서 반환하고 있는 내용을 나타낸다. 함수에서 반환하는 내용을 보면 마치 HTML을 작성하는 것 같지만 위 코드는 HTML이 아니다!! 그렇다고 문자열 템플릿도 아니다!! 이런 코드는 JSX라고 부른다!!! 본격적으로 JSX에 대해 알아보자!
리액트에서 'JSX' 라는 특별한 문법으로 엘리먼트를 만들어 사용자에게 UI가 실제로 어떻게 표현될 것인지 나타낸다. JSX는 Javascript에 XML을 추가한 Javascript를 확장한 문법으로, 공식적인 자바 스크립트 문법은 아닙니다. 하지만 가독성이 높고 이해하기 쉬운, 리액트만의 특별한 스크립트 문법이다.
function App() {
const HelloBlock = <h1>Hello React!</h1>;
return(
<div>
{HelloBlock}
</div>
);
}
여기서 "Hello! React" 가 마치 XML 코드처럼
태그에 감싸져 있는 것을 볼 수 있다. 이렇게 XML태그로 감싸듯 HTML 태그로 감싸 "엘리먼트(element)"를 만드는 문법을 JSX 문법이라고 한다.JSX에서는 우리가 알고 있는 div나 span 같은 HTML 태그를 사용할 수 있을 뿐만 아니라, 앞으로 만들 컴포넌트도 JSX안에서 작성할 수 있다. App.js에서는 App 컴포넌트가 만들어져있죠? src/index.js 파일을 열어 보면 이 App 컴포넌트를 마치 HTML 태그 쓰듯이 그냥 작성한다.
반드시 부모 요소 하나가 감싸는 형태
선언한 컴포넌트 안에 여러 가지 태그가 있다면 반드시 div 또는 다른 컴포넌트 등의 부모 요소 하나로 감싸야 합니다. 그렇다면 왜 반드시 부모 요소가 필요할 까요? 반드시에는 이유가 있습니다. 그 이유는 Virtual DOM이 컴포넌트의 변경을 빠르게 감지 하여 비교 가능하도록 설계되어 있고, DOM은 "트리 형태"로 되어 있기 때문에, 반드시 부모 노드가 필요합니다.
※ 리액트 16ver 이상은 Fragment 기능을 사용하면 반드시 div 로 감싸지 않아도 되며, Fragment로 감싸면 됩니다.
여기서 DOM 트리에 대해서 더 알고 싶으면 이것을 보고 오자! DOM 트리
function App() {
return(
<div>
<h1>Hello</h1>
<h2>React</h2>
</div>
);
}
요소 여러 개가 부모 요소 하나에 의하여 감싸져 있는 정상적인 코드이다.
function App() {
return(
<h1>Hello</h1>
<h2>React</h2>
);
}
만약 이런식으로 작성한다면 아래와 같이 애러가 뜬다..(사진이 너무 큰데 줄이는 방법을 모르겠다ㅋㅋ) 애러가 나는 이유는 요소 여러 개가 요소 하나에 의하여 감싸져 있지 않기 때문에 오류가 발생했다
리액트 컴포넌트에서 요소 여러 개를 왜 하나의 요소로 꼭 감싸 주어야 할까요?? 그것은 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포낸트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문이다.
만약!! 여기서 꼭 내가 div를 사용하기 싫다면 리액트 v16 이상부터 도입된 Fragment라는 기능을 사용하면 된다.
import {Fragment} from 'react';
function App() {
return (
<Fragment>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니?</h2>
</Fragment>
);
}
export default App;
코드 상단 import 구문에서 react 모듈에 들어 있는 Fragment라는 컴포넌트를 추가로 불러 온다. Fragment는 다음과 같은 형태로도 표현 가능하다.
function App() {
return (
<>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니?</h2>
</>
);
}
export default App;
JSX 안에서는 자바스크립트 표현식을 쓸 수 있다. 자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 된다.
function App() {
const name = '리액트';
return (
<>
<h1>{name} 안녕!</h1>
<h2>잘 작동하니?</h2>
</>
);
}
export default App;
여기서 ES6의 const와 let에 관해 알고 있으면 좋다. 여기서 설명하기에는 너무 길어질꺼 같아서 이것을 참고 하자!! var,let,const 차이점
JSX 내부의 자바스크립트 표현식에서 if 문을 사용할 수는 없다. 하지만 조건에 따라 다른 내용을 렌더링해야 할 때는 JSX 밖에서 if 문을 사용하여 사전에 값을 설정하거나, { } 안에 조건부 연산자를 사용하면 된다. 조건부 연산자의 또 다른 이름은 삼항 연산자이다.
function App() {
const name = '리액트';
return(
<div>
{name === '리액트' ? {
<h1>리액트입니다.</h1>
} : {
<h2>리액트가 아닙니다.</h2>
)}
</div>
);
}
개발하다 보면 특정 조건을 만족할 떄 내용을 보여 주고, 만족하지 않을 때 아예 아무것도 렌더링 하지 않아야 하는 상황이 올 수 있다. 이럴 떄도 조건부 연산자를 통해 구현할 수는 있다.
function App() {
const name = '리액트';
return <div>{name === '리액트' ? <h1>리액트입니다.</h1> : null</div>;
}
위 코드와 같이 null을 렌더링하면 아무것도 보여 주지 않는다. 이것보다도 짧은 코드로 작성할 수 있다. 다음과 같이 && 연산자를 사용해 조건부 렌더링을 할 수 있다.
function App() {
const name = '리왝트';
return <div>{name === '리액트' && <h1>리액트입니다.</h1>}</div>;
}
이렇게 코드를 작성하고 나면 브라우저에는 아무것도 나타나지 않을 것이다.
&& 연산자로 조건부 렌더링을 할 수 있는 이유는 리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문이다. 여기서 주의!!!! falsy한 값인 0은 예외적으로 화면에 나타난다.
책에서는 리액트 컴포넌트에서는 함수에서 undefined만 반환하여 랜더링하는 상황을 만들면 안된다고 한다. 예를 들면 이런 코드는 오류가 난다.
function App() {
const name = undefined;
return name;
}
export default App;
터미널에서 이런 오류가 나타났다. 하지만 localhost에서는 그냥 아무것도 나오지 않았다. 실행이 되는건지 모르겠다... 이해가 안 돼서 찾아보니 react componenet에서는 함수에서 undefined를 반환하여 렌더링하는 상황을 만들면 안된다. 라고 했다. 그냥 일단 그렇게 이해하고 있어야겠다. (좀 더 알아보겠다.) 리액트에서 코드를 실행해서 터미널을 보는 것이 맞는지도 모르겠다 ;;
만약 어떤 값이 undefined일 수도 있다면, OR(||) 연산자를 사용하면 해당 값이 undefined일 때 사용 할 값을 지정할 수 있으므로 간단하게 오류를 방지할 수 있다.
import './App.css'
function App() {
const name = undefined;
return name || '값이 undefined입니다';
}
export default App;
반면 JSX 내부에서 undefined를 렌더링하는 것은 괜찮다.
import './App.css'
function App() {
const name = undefined;
return <div>{name}</div>;
}
export default App;
name 값이 undefined일 때 보여 주고 싶은 문구가 있다면 다음과 같이 코드를 작성하면 된다.
import './App.css'
function App() {
const name = undefined;
return <div>{name || '리액트'}</div>;
}
export default App;
리액트에서는 DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 객체 형태로 넣어야 한다. 예를 들어 background-color처럼 - 문자가 포함되는 이름이 있는 것은 - 문자를 없애고 카멜 표기법으로 작성해야 한다. 따라서 background-color는 backgroundColor로 작성한다.
일단 HTML에서 CSS 클래스를 사용할때는
와 같이 class라는 속성을 설정한다. 하지만 JSX에서는 class가 아닌 className으로 설정해 주어야 한다.리액트를 다루는 기술 - 김민준
https://hanamon.kr/%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-component%EB%9E%80/
https://life-with-coding.tistory.com/506
https://wooder2050.medium.com/%EC%9D%B4%EB%A1%A0-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-dom-%ED%8A%B8%EB%A6%AC-96ca3008a474