์ƒˆ์†Œ์‹

React

[React] 03. ์ปดํฌ๋„ŒํŠธ

  • -

๐Ÿ“Œ. ์ปดํฌ๋„ŒํŠธ

์•ž์„  ํฌ์ŠคํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ(component)๋Š” ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์—์„œ ํŠน์ • ๋ถ€๋ถ„์ด ์–ด๋–ป๊ฒŒ ์ƒ๊ธธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์„ ์–ธ์ฒด๋ผ๊ณ  ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ๋‘ ๊ฐ€์ง€๋กœ ์„ ์–ธ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋น„๊ตํ•˜๋ฉฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋ Œ๋”๋ง ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” props์™€ state์˜ ์ฐจ์ด์ ๊ณผ ์„ ์–ธ ๋ฐฉ์‹์„ ๋ฐฐ์šฐ๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ I. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ

๐Ÿ“š 1. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ

์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ฐฉ์‹์€ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” state ๊ธฐ๋Šฅ ๋ฐ ๋ผ์ดํ”„ ์‚ฌ์ดํด ๊ธฐ๋Šฅ, ์ž„์˜ ๋ฉ”์„œ๋“œ ์ •์˜ ๋“ฑ์—์„œ ์ฐจ์ด๊ฐ€ ๋‚ฉ๋‹ˆ๋‹ค.

๊ฐ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ ์ฐจ์ด์ ์„ ๋น„๊ตํ•ด๋ณด์ž.

(1) ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ

import {Component} from "react";

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

export default App;

(2) ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ

import './App.css';

function App() {
    const name = "๋ฆฌ์•กํŠธ";
    return <div className='react'> {name} </div>;
}

export default App;

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ์„ ์–ธํ•˜๊ธฐ ํŽธ๋ฆฌ
  • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ ์ž์›์„ ๋œ ์‚ฌ์šฉํ•˜๊ณ , ์‹ค์ œ ๋ฐฐํฌํ•  ๋•Œ๋„ ๊ฒฐ๊ณผ๋ฌผ์˜ ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ ๋” ์ž‘์Šต๋‹ˆ๋‹ค.
  • ๋ฆฌ์•กํŠธ v16.8 ์—…๋ฐ์ดํŠธ๋กœ state์™€ ๋ผ์ดํ”„์‚ฌ์ดํด API๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ v16.8 ์—…๋ฐ์ดํŠธ๋กœ Hooks๊ฐ€ ๋„์ž…๋˜์—ˆ๊ณ  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋„ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ™์ด ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ ๊ณต์‹ ๋งค๋‰ด์–ผ์—์„œ๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ „์˜ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋“ค์˜ ์œ ์ง€ ๋ฐ ๋ณด์ˆ˜๋ฅผ ์œ„ํ•˜์—ฌ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋„ ๋ฐ˜๋“œ์‹œ ์•Œ์•„๋‘์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ II. ์ฒซ ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ

๐Ÿ“š 1. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑํ•˜๊ธฐ

์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์Œ์˜ ์„ธ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ
  2. ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ
  3. ๋ชจ๋“ˆ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

VS ์ฝ”๋“œ์—์„œ ํŒŒ์ผ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ src ๋””๋ ‰ํ„ฐ๋ฆฌ - [์šฐํด๋ฆญ] - <ํŒŒ์ผ์ด๋ฆ„>.js ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“š 2. ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

์•ž์œผ๋กœ๋Š” NewComponent.js ํŒŒ์ผ์„ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด ์ฝ”๋“œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

// NewComponent.js

const NewComponent = () => {
    return <div> ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ ์ปดํฌ๋„ŒํŠธ </div>
};

export default NewComponent;

์œ„ ์ฝ”๋“œ๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. JavaScript ES6 ๋ฌธ๋ฒ•์—์„œ function ํ‚ค์›Œ๋“œ ์™ธ์—๋„ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ์—ฐ์‚ฐํ•˜์—ฌ ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•ด์•ผํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“š 3. ๋ชจ๋“ˆ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

(1) ๋ชจ๋“ˆ ๋‚ด๋ณด๋‚ด๊ธฐ

export default NewComponent;

์ด ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์ด ํŒŒ์ผ์„ import ํ•  ๋•Œ, ์œ„ ํด๋ž˜์Šค๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค

(2) ๋ชจ๋“ˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

// App.js

import NewComponent from "./NewComponent";

const App = () => {
  return <NewComponent />
}

export default App;

import ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด NewComponent ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ ์ƒˆ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ III. props

๐Ÿ“š 1. props ๊ฐ’ ์‚ฌ์šฉ

props๋Š” properties์˜ ์ค„์ž„๋ง๋กœ ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด props ๊ฐ’์€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(1) JSX ๋‚ด๋ถ€์—์„œ props ๋ Œ๋”๋ง

NewComponent.js์— ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. 

// NewComponent.js

const NewComponent = props => {
    return <div> {props.prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. </div>
};
 
export default NewComponent;
  • ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์—์„œ program์ด๋ผ๋Š” props๋ฅผ ๋ Œ๋”๋งํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ
  • props ๊ฐ’์€ ๋งค๊ฐœ๋ณ€์ˆ˜(ํŒŒ๋ผ๋ฏธํ„ฐ)๋กœ ์‚ฌ์šฉ

(2) ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ props ๊ฐ’ ์ง€์ •ํ•˜๊ธฐ

NewComponent๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ(App.js)์— ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

// App.js

import NewComponent from "./NewComponent";

const App = () => {
  return <NewComponent prog="๋ฆฌ์•กํŠธ" />;
};

export default App;
  • ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ props์˜ ๊ฐ’์„ ์ง€์ •

๐Ÿ“š 2. props ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •: defaultProps

์œ„์˜ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ prog ๊ฐ’์„ ์ง€์šฐ๋ฉด prog ์ž๋ฆฌ์— ์•„๋ฌด ๋‚ด์šฉ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. props ๊ฐ’์„ ๋”ฐ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ณด์—ฌ์ค„ ๊ธฐ๋ณธ๊ฐ’์€ defaultProps๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. .

// NewComponent.js

const NewComponent = props => {
    return <div> {props.prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. </div>;
};

NewComponent.defaultProps = {
    prog : "REACT"
}

export default NewComponent;

NewComponent.js ํŒŒ์ผ์— defaultProps์„ ์ด์šฉํ•ด ๊ธฐ๋ณธ ๊ฐ’์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“š 3. ํƒœ๊ทธ ์‚ฌ์ด์˜ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” children

๋ฆฌ์•กํŠธ์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ ์‚ฌ์ด์˜ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” props๋„ ์žˆ์Šต๋‹ˆ๋‹ค. children์ด๋ผ๋Š” ๊ฐ’์„ ํ†ตํ•ด ํƒœ๊ทธ ์‚ฌ์ด์— ์ž‘์„ฑํ•œ ๋‚ด์šฉ์„ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ์—์„œ๋Š” props.children์„ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

(์ฝ”๋“œ ๋‚ด์˜ (...) ์€ ์ƒˆ๋กœ ์ž‘์„ฑ๋œ ๋ถ€๋ถ„ ์™ธ์˜ ์ฝ”๋“œ๋Š” ์ด์ „์— ์ž‘์„ฑํ•œ ์ฝ”๋“œ์™€ ๋™์ผํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.)

// NewComponent.js

const NewComponent = props => {
    return (
        <div> 
            {props.prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. <br/>
            children์˜ ๊ฐ’์€ {props.children}์ž…๋‹ˆ๋‹ค.
        </div>
    );    
};
(...)
export default NewComponent;
// App.js

import NewComponent from "./NewComponent";

const App = () => {
  return <NewComponent> ~ํƒœ๊ทธ ์‚ฌ์ด~ </NewComponent> 
}

export default App;

๐Ÿ“š 4. ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ๋ฌธ๋ฒ•์„ ํ†ตํ•ด props ๋‚ด๋ถ€ ๊ฐ’ ์ถ”์ถœํ•˜๊ธฐ

props ๊ฐ’์„ ์กฐํšŒํ•  ๋•Œ๋งˆ๋‹ค props.prog, props.children ๊ฐ™์ด prog. ์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ES6์˜ ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด๋ถ€ ๊ฐ’์„ ๋” ํŽธํžˆ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// NewComponent.js

const NewComponent = props => {
    const {prog, children} = props;
    return (
        <div> 
            {prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. <br/>
            children์˜ ๊ฐ’์€ {children}์ž…๋‹ˆ๋‹ค.
        </div>
    );    
};
(...)
export default NewComponent;
  • ๊ฐ์ฒด์—์„œ ๊ฐ’์„ ์ถ”์ถœํ•˜๋Š” ๋ฌธ๋ฒ•์„ ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น(destructing assignment)๋ผ๊ณ  ๋ถ€๋ฆ„
  • ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ฌธ๋ฒ•์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆผ

ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ถ€๋ถ„์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๊ฐ์ฒด๋ผ๋ฉด ๊ฐ’์„ ๋ฐ”๋กœ ๋น„๊ตฌ์กฐํ™”ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// NewComponent.js

const NewComponent = ({prog, children}) => {
    return (
        <div> 
            {prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. <br/>
            children์˜ ๊ฐ’์€ {children}์ž…๋‹ˆ๋‹ค.
        </div>
    );    
};
(...)
export default NewComponent;

๐Ÿ“š 5. propTypes๋ฅผ ํ†ตํ•œ props ๊ฒ€์ฆ

์ปดํฌ๋„ŒํŠธ์˜ ํ•„์ˆ˜ props๋ฅผ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ํƒ€์ž…์„ ์ง€์ •ํ•  ๋•Œ๋Š” propTypes๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. propTypes๋ฅผ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ defaultProp์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. propTypes์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์ƒ๋‹จ์— import๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

import PropTypes from 'prop-types';

(1) ํƒ€์ž… ์„ค์ •ํ•˜๊ธฐ 

// NewComponent.js

import PropTypes from 'prop-types';

(...)

NewComponent.propTypes = {
	prog: PropTypes.string
};

export default NewComponent;
  • prog์˜ ๋‚ด์šฉ์€ ๋ฐ˜๋“œ์‹œ String์œผ๋กœ ์ง€์ •๋˜์–ด์•ผ ํ•จ
  • ์ž˜๋ชป๋œ ํƒ€์ž…์œผ๋กœ ๊ฐ’์„ ์ง€์ •ํ•œ ๋’ค ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Console ํƒญ์„ ์—ด๋ฉด ์˜ค๋ฅ˜ ์ฐฝ์ด ๋œธ

(2) isRequired๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์ˆ˜ propTypes ์„ค์ •

propTypes์„ ์ง€์ •ํ•  ๋•Œ ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

// NewComponent.js

import { PropTypes } from "prop-types";

const NewComponent = ({prog, children, age}) => {
    return (
        <div> 
            {prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. <br/>
            children์˜ ๊ฐ’์€ {children}์ž…๋‹ˆ๋‹ค. <br/>
            ์ €์˜ ๋‚˜์ด๋Š” {age}์„ธ ์ž…๋‹ˆ๋‹ค.
        </div>
    );    
};

NewComponent.defaultProps = {
    prog : "๋ฆฌ์•กํŠธ"
}

NewComponent.propTypes = {
    prog: PropTypes.string,
    age: PropTypes.number.isRequired
};

export default NewComponent;

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์ธ App.js์—์„œ age์˜ ๊ฐ’์ด ์„ค์ •๋˜์ง€ ์•Š๋Š” ๋‹ค๋ฉด ์ฝ˜์†”์ฐฝ์—์„œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

// App.js

import NewComponent from "./NewComponent";

const App = () => {
  return(
    <NewComponent prog = "React" age = {100} >
      ~ children ๊ฐ’ ~
    </NewComponent> 
  ) 
}

export default App;

(3) PropTypes์˜ ์ข…๋ฅ˜

https://github.com/facebook/prop-types ์—์„œ PropTypes์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“š 6. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ props ์‚ฌ์šฉํ•˜๊ธฐ

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ props๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” render ํ•จ์ˆ˜์—์„œ this.props๋ฅผ ์กฐํšŒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. defaultProps์™€ propTypes๋Š” ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ props ๊ฐ’์„ ์กฐํšŒํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

// NewComponent.js

import { Component } from "react";
import PropTypes from "prop-types";

class NewComponent extends Component {
    render() {
        const {prog, children, age} = this.props; //๋น„๊ตฌ์กฐํ™” ํ• ๋‹น
        return (
            <div>
                {prog}์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. <br/>
                children์˜ ๊ฐ’์€ {children}์ž…๋‹ˆ๋‹ค. <br/>
                ์ €์˜ ๋‚˜์ด๋Š” {age}์„ธ ์ž…๋‹ˆ๋‹ค.
            </div>
        )
    }
}
NewComponent.defaultProps = {
    prog : "๋ฆฌ์•กํŠธ"
}

NewComponent.propTypes = {
    prog: PropTypes.string,
    age: PropTypes.number.isRequired
};

export default NewComponent;

defaultProps์™€ propTypes๋Š” class ๋‚ด๋ถ€์—์„œ๋„ ์ง€์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

// NewComponent.js

import { Component } from "react";
import PropTypes from "prop-types";

class NewComponent extends Component {    
    static defaultProps = {
        prog : "๋ฆฌ์•กํŠธ"
    };
    static propTypes = {
        prog: PropTypes.string,
        age: PropTypes.number.isRequired
    }
    render() {
    	( ... )
    }
}

export default NewComponent;

๐Ÿ“Œ IV. state

๐Ÿ“š 1. state

  • state๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ฐ”๋€” ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์˜๋ฏธ
  • props๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๊ณผ์ •์—์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„ค์ •ํ•˜๋ฉฐ ์ž์‹ ์€ ํ•ด๋‹น props๋ฅผ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉ
  • state๋Š” ์ปดํฌ๋„ŒํŠธ ์ž์ฒด์ ์œผ๋กœ ์ง€๋‹Œ ๊ฐ’์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ผ๋ฐ˜ ๋ณ€์ˆ˜๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ html์— ์ž๋™ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์ง€๋งŒ, state๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด html์— ์žฌ๋žœ๋”๋ง ํ•ด์คŒ
    => ๊ฐ’์˜ ๋ณ€ํ™”๊ฐ€ ์ž์ฃผ ์žˆ์„ ๋•Œ state๋ฅผ ์‚ฌ์šฉ
  • ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” state, ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” useState๋ฅผ ์‚ฌ์šฉ

๐Ÿ“š 2. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ state

ํด๋ฆญ์œผ๋กœ ์ˆซ์ž๋ฅผ ๋Š˜์ด๋Š” Counter.js๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค.

// Counter.js

import { Component } from "react";

class Counter extends Component {
    constructor(props) {
        super(props);

        this.state = {
            number: 0 // state ์ดˆ๊นƒ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ
        };
    }
    render() {
        const {number} = this.state; // state ์กฐํšŒ์‹œ this.state๋ฅผ ์กฐํšŒ
        return (
            <div>
                <h1> {number} </h1>
                <button
                    /* onClick ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ฆญ ์‹œ ์ˆซ์ž๋ฅผ ๋Š˜๋ ค์ฃผ๋Š” ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ */
                    onClick = {() => {
                        /* this.setState๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ state์— ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ง€์ • */
                        this.setState( {number: number +1 } );
                    }}
                >
                    +1
                </button> 
            </div>
        );
    }
}

export default Counter;

๐Ÿ“š 3. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ useState ์‚ฌ์šฉํ•˜๊ธฐ

(1) ๋ฐฐ์—ด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น

  • ๋ฐฐ์—ด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น์€ ๊ฐ์ฒด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น๊ณผ ๋น„์Šทํ•จ
  • ๋ฐฐ์—ด ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๊ฐ’์„ ์‰ฝ๊ฒŒ ์ถ”์ถœํ•˜๋„๋ก ํ•˜๋Š” ๋ฌธ๋ฒ•
  • Destructing ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ํ˜•ํƒœ๋ฅผ ๋งž์ถ”์–ด ๊ฐ’์„ ์‰ฝ๊ฒŒ ํ• ๋‹น
const array = [1, 2];
const one = array[0];
const two = array[1];

์œ„ ์ฝ”๋“œ๋Š” ๋ฐฐ์—ด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น์„ ํ†ตํ•ด ๋” ๊ฐ„๋‹จํžˆ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const array = [1, 2];
const [one, two] = array;

(2) useState ์‚ฌ์šฉํ•˜๊ธฐ

๋ฆฌ์•กํŠธ 16.8 ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ state๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—…๋ฐ์ดํŠธ ์ดํ›„, Hooks๊ฐ€ ์ƒ๊ธฐ๋ฉด์„œ  useState ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ state๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Hooks์˜ ์ข…๋ฅ˜ ์ค‘ ํ•˜๋‚˜์ธ useState๋ฅผ ๋จผ์ € ๋ฐฐ์šฐ๊ฒ ์Šต๋‹ˆ๋‹ค.

useState๋Š” ๋ฐฐ์—ด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ๋ฌธ๋ฒ•๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. useState๋ฅผ ํ™œ์šฉํ•œ ์ฝ”๋“œ๋ฅผ Say.js์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

// Say.js

import { useState } from "react";

const Say = () => {
    const [message, setMessage] = useState('');
    const onClickEnter = () => setMessage("์•ˆ๋…•ํ•˜์„ธ์š”!");
    const onClickLeave = () => setMessage("์•ˆ๋…•ํžˆ๊ฐ€์„ธ์š”!");

    return (
        <div>
            <button onClick={onClickEnter}>์ž…์žฅ</button>
            <button onClick={onClickLeave}>ํ‡ด์žฅ</button>
            <h1> {message} </h1>
        </div>
    );
};

export default Say;
  • useState ํ•จ์ˆ˜ ์ธ์ž์—๋Š” ์ƒํƒœ์˜ ์ดˆ๊นƒ๊ฐ’์„ ์ง€์ •, ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ์–ด๋„ ๊ดœ์ฐฎ์Œ
  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฐฐ์—ด์ด ๋ฐ˜ํ™˜
    *  ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋Š” ํ˜„์žฌ ์ƒํƒœ
    *  ๋ฐฐ์—ด์˜ ๋‘ ๋ฒˆ์งธ ์›์†Œ๋Š” ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ์–ด์ฃผ๋Š” ํ•จ์ˆ˜,  setter ํ•จ์ˆ˜
// App.js

import Say from "./Say";

const App = () => {
  return <Say />
}

export default App;

๐Ÿ“š 4. ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ useState ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๊ธฐ

// Say.js

import { useState } from "react";

const Say = () => {
    const [message, setMessage] = useState('');
    const onClickEnter = () => setMessage("์•ˆ๋…•ํ•˜์„ธ์š”!");
    const onClickLeave = () => setMessage("์•ˆ๋…•ํžˆ๊ฐ€์„ธ์š”!");

    const [color, setColor] = useState('black');

    return (
        <div>
            <button onClick={onClickEnter}>์ž…์žฅ</button>
            <button onClick={onClickLeave}>ํ‡ด์žฅ</button>
            <h1 style = {{ color }}> {message} </h1>
            <button style={{ color: 'red'}} onClick={() => setColor('red')}>
                ๋นจ๊ฐ„์ƒ‰
            </button>
            <button style={{ color: 'green'}} onClick={() => setColor('green')}>
                ์ดˆ๋ก์ƒ‰
            </button>
            <button style={{ color: 'blue'}} onClick={() => setColor('blue')}>
                ํŒŒ๋ž€์ƒ‰
            </button>
        </div>
    );
};

export default Say;

๐Ÿ“š 5. state ์‚ฌ์šฉ ์‹œ ์ฃผ์˜ ์‚ฌํ•ญ

  • state ๊ฐ’์„ ๋ฐ”๊ฟ€๋•Œ๋Š” setState ํ˜น์€ useState๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ์„ธํ„ฐ(setter) ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
  • ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ๋•Œ๋Š” ์‚ฌ๋ณธ์— ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๊ทธ ์‚ฌ๋ณธ์˜ ์ƒํƒœ๋ฅผ setState๋‚˜ ์„ธํ„ฐ ํ•จ์ˆ˜๋กœ ์—…๋ฐ์ดํŠธ
  • ์‚ฌ๋ณธ์€ spread ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐฐ์—ด์˜ ์‚ฌ๋ณธ์€ ๋‚ด์žฅ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉ

 

 

 

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.