리액트 개요

  • create-react-app으로 리액트 프로젝트 생성.
    npm init react-app <폴더 이름> 혹은 해당 폴더 안에 들어간 후 터미널에서 npm init react-app .
  • 개발모드 실행: npm run start
  • 개발모드 종료: Ctrl + C
  • 리액트 개발자 도구: React Developer Tools (크롬 확장 프로그램)

JSX

JSX는 자바스크립트의 확장 문법이다.

1
2
3
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<h1>안녕 리액트!</h1>);

HTML과 다른 속성명

  1. 속성명은 카멜케이스로 작성한다.
  • onclick, onblur, onfocus, tabindex 같은 이벤트 속성 및 속성들은 onClick, onBlur, onFocus, onMouseDown, onMouseOver, tabIndex처럼 작성되어야 한다.
  • 예외적으로 비표준 속성을 다룰 때 활용하는 data-* 속성은 기존 HTML 문법 그대로 작성하여야 한다.
  1. 자바스크립트 예약어와 같은 속성명은 사용할 수 없다.
  • for, class 등과 같은 자바스크립트 문법에 해당하는 예약어와 똑같은 이름의 속성명은 사용 불가하다.
  • HTML의 for의 경우 htmlFor으로, class의 경우 className으로 작성하여야 한다.

Fragment

JSX 문법을 활용할 때는 반드시 하나의 요소로 감싸주어야 한다. 여러 개의 요소를 작성하면 오류가 발생하므로 여러 태그를 감싸는 부모 태그를 만들어 하나의 요소를 만들어 주어야 한다.

1
2
3
4
5
6
7
8
9
import ReactDOM from 'react-dom';

ReactDOM.render(
<div>
<p>안녕</p>
<p>리액트!</p>
</div>,
document.getElementById('root')
);

부모 태그로 감쌀 경우 꼭 필요하지 않은 태그가 생길 수 있으므로 Fragment로 감싸주면 의미 없는 부모 태그를 만들지 않아도 된다.

1
2
3
4
5
6
7
8
9
10
import { Fragment } from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
<Fragment>
<p>안녕</p>
<p>리액트!</p>
</Fragment>,
document.getElementById('root')
);

빈 태그로 감싸는 단축 문법으로 활용 가능하다.

1
2
3
4
5
6
7
8
9
import ReactDOM from 'react-dom';

ReactDOM.render(
<>
<p>안녕</p>
<p>리액트!</p>
</>,
document.getElementById('root')
);

자바스크립트 표현식

  • 중괄호({}) 를 활용하면 자바스크립트 표현식을 넣을 수 있다.
  • 중괄호는 자바스크립트 표현식 을 다룰 때 활용하기 때문에 중괄호 안에서 for, if문 등의 문장은 다룰 수 없다.
  • JSX 문법을 활용할 때 조건문이 필요하다면 조건 연산자를, 반복문이 필요하다면 배열의 반복 메소드를 사용할 수 있다.
1
2
3
4
5
6
7
8
import ReactDOM from 'react-dom';

const product = '맥북';

ReactDOM.render(
<h1>나만의 {product} 주문하기</h1>,
document.getElementById('root')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const product = 'MacBook';
const model = 'Air';
const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/MacBook_with_Retina_Display.png/500px-MacBook_with_Retina_Display.png'

function handleClick(e) {
alert('곧 도착합니다!');
}

ReactDOM.render(
<>
<h1>{product + ' ' + model} 주문하기</h1>
<img src={imageUrl} alt="제품 사진" />
<button onClick={handleClick}>확인</button>
</>,
document.getElementById('root')
);

리액트 엘리먼트

  • JSX 문법으로 작성한 요소는 결과적으로 자바스크립트 객체가 된다. 이러한 객체를 리액트 엘리먼트 라고 한다.
  • 리액트 엘리먼트는 리액트로 화면을 그려내는데 가장 기본적인 요소이다.
  • 이 리액트 엘리먼트를 ReactDOM.render 함수의 아규먼트로 전달하게 되면 리액트가 객체 현태의 값을 해석하여 HTML 형태로 브라우저에 띄워준다.
1
2
3
4
5
import ReactDOM from 'react-dom';

const element = <h1>안녕 리액트!</h1>;
console.log(element);
ReactDOM.render(element, document.getElementById('root'));
1
{$$typeof: Symbol(react.element), type: "h1", key: null, ref: null, props: {…}, …}

리액트 컴포넌트

  • 리액트 컴포넌트는 리액트 앨리먼트를 조금 더 자유로게 다루기 위한 문법이다.
  • 가장 간단한 방법은 자바스크립트의 함수를 활용 하는 것이다.
  • 컴포넌트 함수를 통해 하나의 태그처럼 활용할 수 있다.
  • 이런 특성을 모듈 문법으로 활용하면 훨씬 더 독립적으로 컴포넌트 특성에 집중해서 코드를 작성할 수 있다.
  • 리액트 컴포넌트의 이름은 반드시 첫 글자를 대문자로 작성 해야 한다. 소문자인 경우 오류가 발생한다.

하나의 컴포넌트인 Hello 함수(JSX 문법으로 작성되었으며 하나의 요소를 리턴)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import ReactDOM from 'react-dom';

function Hello() {
return <h1>안녕 리액트</h1>;
}

const element = (
<>
<Hello />
<Hello />
<Hello />
</>
);

ReactDOM.render(element, document.getElementById('root'));
1
2
3
4
5
6
7
import diceBlue01 from './assets/dice-blue-1.svg';

function Dice() {
return <img src={diceBlue01} alt="주사위" />;
}

export default Dice;
1
2
3
4
5
6
7
8
9
10
11
import Dice from './Dice';

function App() {
return (
<div>
<Dice />
</div>
);
}

export default App;

Props

  • 컴포넌트를 작성할 때 컴포넌트에도 속성을 지정할 수 있는데 이렇게 컴포넌트에 지정한 속성들을 Props 라고 한다.
  • Properties의 약자이다.
  • 컴포넌트에 속성을 지정해주면 각 속성이 하나의 객체로 모여서 컴포넌트를 정의한 함수의 첫 번째에 파라미터로 전달된다.
  • props는 객체 형태를 띠고 읬으므로 Destructuring 문법을 활용하여 더 간결하게 코드를 작성할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
import Dice from './Dice';

function App() {
return (
<div>
<Dice color="blue" />
</div>
);
}

export default App;
1
2
3
4
5
6
7
8
import diceBlue01 from './assets/dice-blue-1.svg';

function Dice(props) {
console.log(props)
return <img src={diceBlue01} alt="주사위" />;
}

export default Dice;
1
{ color: "blue" }

Children

  • props에는 children이라는 특별한 프로퍼티가 있다.
  • 컴포넌트를 작성할 때 컴포넌트를 단일 태그가 아니라 여는 태그와 닫는 태그의 형태로 작성하면 그 안에 작성된 코드가 children값에 담긴다.
  • 어떤 정보를 전달할 때는 일반적인 props 속성값을 주로 활용하고, 화면에 보여질 모습을 직관적인 코드로 작성할 떼 children 값을 활용할 수 있다.
  • children을 활용하면 컴포넌트 안에 컴포넌트를 작성할 수 있고 컴포넌트 안에 복잡한 태그를 더 작성할 수 있다.
1
2
3
4
5
function Button({ children }) {
return <button>{children}</button>;
}

export default Button;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Dice from './Dice';

function App() {
return (
<div>
<div>
<Button>던지기</Button>
<Button>처음부터</Button>
</div>
<Dice color="red" num={2} />
</div>
);
}

export default App;

State

  • 상태가 바뀔 때마다 화면을 새롭게 그려내는 방식으로 동작한당.
  • state를 만들고 state를 바꾸기 위해서 useState라는 함수를 활용한다.
  • 보통 Destructuring 문법으로 작성한다. useState 함수가 초깃값을 아규먼트로 받고 그에 대한 실행 결과로 요소 2개를 가진 배열의 형태로 리턴하기 때문이다.
  • 첫 번째 변수는 원하는 state의 이름을 지어주고, 두 번째 변수에는 state 이름 앞에 set을 붙인 다음 카멜 케이스로 이름을 짓는 것이 일반적이다.
  • state는 변수에 새로운 값을 변경하는 것이 아니라 setter 함수를 활용하여야 한다. setter 함수는 호출할 때 전달하는 아규먼트 값으로 state값을 변경한다.
1
2
3
4
5
import { useState } from 'react';
// ...

const [num, setNum] = useState(1);
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { useState } from 'react';
import Button from './Button';
import Dice from './Dice';

function App() {
const [num, setNum] = useState(1);

const handleRollClick = () => {
setNum(3); // num state를 3으로 변경!
};

const handleClearClick = () => {
setNum(1); // num state를 1로 변경!
};

return (
<div>
<Button onClick={handleRollClick}>던지기</Button>
<Button onClick={handleClearClick}>처음부터</Button>
<Dice color="red" num={num} />
</div>
);
}

export default App;

참조형 State

  • 참조형 state를 활용할 땐 반드시 새로운 참조형 값을 만들어서 state를 변경해야 한다.
  • 간단한 방법은 Spread 문법(...)을 활용하는 것이다.
1
2
3
4
5
6
7
8
9
10
// ... 

const [gameHistory, setGameHistory] = useState([]);

const handleRollClick = () => {
const nextNum = random(6);
setGameHistory([...gameHistory, nextNum]); // state가 제대로 변경된다!
};

// ...

디자인을 적용하는 방법

이미지 불러오기

이미지 파일은 import 구문을 통해 불러오고, 불러온 이미지 주소를 src 속성으로 사용하면 된다.

1
2
3
4
5
6
7
import diceImg from './assets/dice.png';

function Dice() {
return <img src={diceImg} alt="주사위 이미지" />;
}

export default App;

인라인 스타일

  • 인라인 스타일은 문자열이 아닌 객체형 으로 사용한다.
  • 프로퍼티 이름은 CSS 속성 이름으로, 프로퍼티 값은 CSS 속성 값으로 기재한다.
  • borderRadius처럼 대시 기호 없이 카멜 케이스 로 써야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
import diceImg from './assets/dice.png';

const style = {
borderRadius: '50%',
width: '120px',
height: '120px',
};

function Dice() {
return <img style={style} src={diceImg} alt="주사위 이미지" />;
}

export default App;

클레스네임 사용하기

  • CSS 파일에 정의된 클래스명을 className prop에 문자열로 넣어준다.
  • 재사용성을 고려하여 className prop을 부모 컴포넌트에서 받으면 더 좋다.
1
2
3
4
5
6
7
8
9
import diceImg from './assets/dice.png';
import './Dice.css';

function Dice({ className = '' }) {
const classNames = `Dice ${className}`;
return <img className={classNames} src={diceImg} alt="주사위 이미지" />;
}

export default App;

편리하게 클래스네임을 쓰는 방법

  • className을 템플릿 문자열로 사용할 경우 개수가 늘어날수록 알아보기 힘들어진다는 문제점이 있다.
  • 라이브러리를 사용하여 미리 만들어놓은 코드를 이용하여 편하게 개발하는 방법이 있다.
  • classnames라는 라이브러리는 클레스네임에만 집중할 수 있어 읽기 편해진다.
  • classnames 라이브러리는 npm install classnames으로 설치하고 import로 불러와 사용할 수 있다.

템플릿 문자열을 사용한 예

1
2
3
4
5
6
function Button({ isPending, color, size, invert, children }) {
const classNames = `Button ${isPending ? 'pending' : ''} ${color} ${size} ${invert ? 'invert' : ''}`;
return <button className={classNames}>{children}</button>;
}

export default Button;

배열을 사용한 예

1
2
3
4
5
6
7
8
9
10
11
12
function Button({ isPending, color, size, invert, children }) {
const classNames = [
'Button',
isPending ? 'pending' : '',
color,
size,
invert ? 'invert' : '',
].join('');
return <button className={classNames}>{children}</button>;
}

export default Button;

classnames 라이브러리를 사용한 예

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import classNames from 'classnames';

function Button({ isPending, color, size, invert, children }) {
return (
<button
className={classNames(
'Button',
isPending && 'pending',
color,
size,
invert && 'invert',
)}>
{ children }
</button >
);
}

export default Button;

REFERENCE
코드잇 온라인 강의 React 프론트엔드 개발

  • © 2020-2025 404 Not Found
  • Powered by Hexo Theme Ayer