๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

[๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ ] 3์žฅ - Component

2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-0

์ด ๊ธ€์€ ๊น€๋ฏผ์ค€(velopert)๋‹˜์˜ ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ ์„์ฐธ์กฐํ•˜์—ฌ ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๋ฆฌ์•กํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ๋Š”๋‹จ์ˆœํ•œ ํ…œํ”Œ๋ฆฟ ์ด์ƒ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ผ UI๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  , ๋ผ์ดํ”„์‚ฌ์ดํด API๋ฅผ ์ด์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ๋‚˜ํƒ€๋‚  ๋•Œ, ์‚ฌ๋ผ์งˆ ๋•Œ, ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚  ๋•Œ ์ฃผ์–ด์ง„ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ž„์˜ ๋ฉ”์„œ๋“œ๋กœ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์„ ๋ถ™์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ์—๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋จผ์ € ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋ถ€ํ„ฐ ์•Œ์•„๋ณธ๋‹ค.


ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ#

2์žฅ์—์„œ ๋ณธ App.js ์ฒ˜๋Ÿผ function ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ return ํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

๋ฐ˜๋ฉด ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

App.js

import React, {Component} from 'react';
class App extends Component {    render() {        const name = 'react';        return <div classNme="react">{name}</div>;    }}
export default App;

์ฝ”๋“œ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด App class๋Š” ๋ฆฌ์•กํŠธ Component ๋ฅผ ํ™•์žฅํ•˜๊ณ  ์žˆ๊ณ , render() ํ•จ์ˆ˜๋ฅผ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ, render ํ•จ์ˆ˜์—์„œ ๋ณด์—ฌ์ค„ JSX๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ด render ํ•จ์ˆ˜๊ฐ€ ๊ผญ ์žˆ์–ด์•ผ ํ•œ๋‹ค.


ํ•จ์ˆ˜ํ˜• vs ํด๋ž˜์Šคํ˜•#

๊ทธ๋Ÿฌ๋ฉด ์–ด๋–ค ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์— ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ?

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

๋ฆฌ์•กํŠธ ๊ณต์‹ ๋งค๋‰ด์–ผ์—์„œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ๋งŒํผ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ ์  ์ค‘์š”ํ•ด์ง€๊ณ  ์žˆ์ง€๋งŒ, ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ์„ ์•Œ์•„๋‘˜ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.


์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ#

์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” create react-app ์œผ๋กœ ๋งŒ๋“  ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์—์„œ src ๋””๋ ‰ํ† ๋ฆฌ์— ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ NewComponent.js ์„ ์ƒ์„ฑํ•œ๋‹ค.

NewComponent.js

import React from 'react';
const NewComponent = () => {    return <div>Hello React Component!</div>;};
export default NewComponent;

๋ชจ๋“ˆ ๋‚ด๋ณด๋‚ด๊ธฐ(Export) ๋ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ(Import)#

์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋งจ ์•„๋ž˜ ์ค„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ import ํ•  ์ˆ˜์žˆ๋„๋ก export ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

export default NewComponent;

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ import ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ• ์ˆ˜ ์žˆ๋‹ค.

import React from 'react';import NewComponent from './NewComponent';
const App = () => {    return (        <div>            <NewComponent />        </div>    );};
export default App;

props#

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


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

์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ props ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. App.js ์—์„œ์‚ฌ์šฉํ•˜๋Š” NewComponent ์— props ๊ฐ’์„ ์ง€์ •ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค.

App.js

import React from 'react';import NewComponent from './NewComponent';
const App = () => {    return (        <div>            <NewComponent name="younho9" />        </div>    );};
export default App;

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

์ด๋ ‡๊ฒŒ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ NewComponent ์— ์ง€์ •ํ•œ name ์ด๋ผ๋Š” ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด NewComponent ์—์„œ props ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„ ์™€์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

NewComponent.js

import React from 'react';
const NewComponent = (props) => {    return <div>Hello, React Component! I'm {props.name}</div>;};
export default NewComponent;

props ๊ธฐ๋ณธ๊ฐ’ ์„ค์ • : defaultProps#

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

import React from 'react';
const NewComponent = (props) => {    return <div>Hello, React Component! I'm {props.name}</div>;};
NewComponent.defaultProps = {    name: 'default name',};
export default NewComponent;

ํƒœ๊ทธ ์‚ฌ์ด์˜ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” children#

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, children ์ด๋ผ๋Š” props ๋Š” ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ ์‚ฌ์ด์˜๋‚ด์šฉ์„ ๋ณด์—ฌ์ค€๋‹ค.

App.js

import React from 'react';import NewComponent from './NewComponent';
const App = () => {    return <NewComponent>React</NewComponent>;};
export default App;

์œ„ ์ฝ”๋“œ์—์„œ NewComponent ํƒœ๊ทธ ์‚ฌ์ด์— ์ž‘์„ฑํ•œ React ๋ผ๋Š” ๋ฌธ์ž์—ด์„ NewComponent ๋‚ด๋ถ€์—์„œ ๋ณด์—ฌ์ฃผ๋ ค๋ฉด props.children ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

NewComponent.js

import React from 'react';
const NewComponent = (props) => {    return (        <div>            Hello, React Component! My name is {props.name}            <br />            Children is {props.children}        </div>    );};
NewComponent.defaultProps = {    name: 'default name',};
export default NewComponent;

๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ๋ฌธ๋ฒ•์„ ํ†ตํ•ด props ๋‚ด๋ถ€ ๊ฐ’ ์ถ”์ถœํ•˜๊ธฐ#

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

NewComponent.js

import React from 'react';
const NewComponent = (props) => {    const {name, children} = props;    return (        <div>            Hello, React Component! My name is {name}            <br />            Children is {children}        </div>    );};
NewComponent.defaultProps = {    name: 'default name',};
export default NewComponent;

ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ถ€๋ถ„์—์„œ ๋ฐ”๋กœ ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

NewComponent.js

import React from 'react';
const NewComponent = ({name, children}) => {    return (        <div>            Hello, React Component! My name is {name}            <br />            Children is {children}        </div>    );};
NewComponent.defaultProps = {    name: 'default name',};
export default NewComponent;

propTypes ๋ฅผ ํ†ตํ•œ props ๊ฒ€์ฆ#

์ปดํฌ๋„ŒํŠธ์˜ ํ•„์ˆ˜ props ์ง€์ • ๋˜๋Š” props ํƒ€์ž… ์ง€์ •์„ ์œ„ํ•ด propTypes ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

NewComponent.js

import React from 'react';import PropTypes from 'prop-types';
const NewComponent = ({name, children}) => {    return (        <div>            Hello, React Component! My name is {name}            <br />            Children is {children}        </div>    );};
NewComponent.defaultProps = {    name: 'default name',};
NewComponent.propTypes = {    name: PropTypes.string,};
export default NewComponent;

๋จผ์ € PropTypes ๋ฅผ import ๊ตฌ๋ฌธ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ณ , defaultProps ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ฝ”๋“œ ํ•˜๋‹จ์— ์ •์˜ํ•œ๋‹ค. ๋‹ค์Œ์˜ ์ •์˜๋Š” name ์†์„ฑ์ด ๋ฐ˜๋“œ์‹œ ๋ฌธ์ž์—ด(string) ํ˜•ํƒœ๋กœ ์ „๋‹ฌ๋˜์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋งŒ์•ฝ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” App ์ปดํฌ๋„ŒํŠธ์—์„œ name ๊ฐ’์„ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ ์ˆซ์ž๋กœ ์ „๋‹ฌํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-1


ํ™”๋ฉด์— ๊ฐ’์ด ๋ Œ๋”๋ง๋˜์–ด ๋‚˜ํƒ€๋‚˜๊ธฐ๋Š” ํ•˜์ง€๋งŒ, Console์„ ์—ด์–ด๋ณด๋ฉด ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๋ณผ ์ˆ˜์žˆ๋Š”๋ฐ, NewComponent ์˜ name prop ์— string ํƒ€์ž…์ด ๋“ค์–ด์˜ฌ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์œ ํšจํ•˜์ง€ ์•Š์€ number ํƒ€์ž…์ด ๋“ค์–ด์™”๋‹ค๊ณ  ํ‘œ์‹œํ•˜๊ณ  ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ props ์— ์›ํ•˜๋Š” ํƒ€์ž…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๋˜ํ•œ isRequired ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํ•„์ˆ˜ propTypes ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. propTypes ๋ฅผ์ง€์ •ํ•  ๋•Œ ๋’ค์— isRequired ๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด ๋œ๋‹ค.

NewComponent.propTypes = {    name: PropTypes.string.isRequired,};

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด name prop ์„ ๋งŒ์•ฝ ์ง€์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค.

PropTypes ์—๋Š” ๋ฐฐ์—ด, ํ•จ์ˆ˜, ์ˆซ์ž ๋“ฑ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜์˜ ๋งํฌ์—์„œ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

facebook/prop-types


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

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

NewComponent.js

import React, {Component} from 'react';import PropTypes from 'prop-types';
class NewComponent extends Component {    render() {        const {name, children} = this.props;        return (            <div>                Hello, React Component! My name is {name}                <br />                Children is {children}            </div>        );    }}
NewComponent.defaultProps = {    name: 'default name',};
NewComponent.propTypes = {    name: PropTypes.string.isRequired,};
export default NewComponent;

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” defaultProps ์™€ propTypes ๋ฅผ class ๋‚ด๋ถ€์—์„œ ์ง€์ •ํ• ์ˆ˜๋„ ์žˆ๋‹ค.

import React, {Component} from 'react';import PropTypes from 'prop-types';
class NewComponent extends Component {    static defaultProps = {        name: 'default name',    };
    static propTypes = {        name: PropTypes.string.isRequired,    };    render() {        const {name, children} = this.props;        return (            <div>                Hello, React Component! My name is {name}                <br />                Children is {children}            </div>        );    }}
export default NewComponent;

state#

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

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


ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ state#

src ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ƒˆ๋กœ์šด Counter.js ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค.

Counter.js

import React, {Component} from 'react';
class Counter extends Component {    constructor(props) {        super(props);        this.state = {            number: 0,        };    }    render() {        const {number} = this.state;        return (            <div>                <h1>{number}</h1>                <button                    onClick={() => {                        this.setState({number: number + 1});                    }}                >                    +1                </button>            </div>        );    }}
export default Counter;

์ปดํฌ๋„ŒํŠธ์— state ๋ฅผ ์„ค์ •ํ•  ๋•Œ๋Š”, constructor ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์„ค์ •ํ•œ๋‹ค. ์ด๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ์„ฑ์ž ๋ฉ”์†Œ๋“œ๋กœ, ๋ฐ˜๋“œ์‹œ super(props) ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ, ๋ฆฌ์•กํŠธ Component ํด๋ž˜์Šค๊ฐ€ ์ง€๋‹Œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ์–ด์•ผํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ this.state ๊ฐ’์— ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•ด์ฃผ๋Š”๋ฐ, ์ปดํฌ๋„ŒํŠธ์˜ state ๋Š” ๊ฐ์ฒด ํ˜•์‹์ด์–ด์•ผ ํ•œ๋‹ค.

render ํ•จ์ˆ˜์—์„œ ํ˜„์žฌ state ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” this.state ๋ฅผ ์กฐํšŒํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  button ์˜ onClick ์ด๋ผ๋Š” ๊ฐ’์„ props ๋กœ ๋„ฃ์–ด์ฃผ๋Š”๋ฐ, ์ด๋Š” ๋ฒ„ํŠผ์„ ํด๋ฆญํ• ๋•Œ ํ˜ธ์ถœ ์‹œํ‚ฌ ํ•จ์ˆ˜๋ฅผ ์„ค์ •ํ•œ๋‹ค. (์ด๋ฒคํŠธ)

์ด๋ฒคํŠธ๋กœ ์„ค์ •ํ•  ํ•จ์ˆ˜๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค. ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋Š” this.setState ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ด๋Š” state ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.


์ด์ œ Counter ์ปดํฌ๋„ŒํŠธ๋ฅผ App์—์„œ ๋ถˆ๋Ÿฌ์™€ ๋ Œ๋”๋งํ•œ๋‹ค.

App.js

import React from 'react';import Counter from './Counter';
const App = () => {    return <Counter />;};
export default App;

2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-2


๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ˆซ์ž๊ฐ€ 1์”ฉ ์˜ฌ๋ผ๊ฐ„๋‹ค.


์•ž์—์„œ constructor ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ state ์˜ ์ดˆ๊ธฐ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

import React, {Component} from 'react';
class Counter extends Component {    state = {        number: 0,    };    render() {        const {number} = this.state;        return (            <div>                <h1>{number}</h1>                <button                    onClick={() => {                        this.setState({number: number + 1});                    }}                >                    +1                </button>            </div>        );    }}
export default Counter;

this.setState ์— ๊ฐ์ฒด ๋Œ€์‹  ํ•จ์ˆ˜ ์ธ์ž ์ „๋‹ฌํ•˜๊ธฐ#

this.setState ๋Š” state ๊ฐ’์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ๋งŒ์•ฝ onClick ํ•จ์ˆ˜๋‚ด๋ถ€๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

onClick={() => {  this.setState({ number: number + 1 });  this.setState({ number: this.state.number + 1 });}}

this.setState ๋ฅผ ๋‘ ๋ฒˆ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Click ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ˆซ์ž๊ฐ€ 2์”ฉ์ฆ๊ฐ€ํ•  ๊ฒƒ ๊ฐ™์ง€๋งŒ, ์ˆซ์ž๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š”๋ฐ, this.setState ๋ฅผ ํ•˜๊ณ  ๋‚˜์„œ state ๊ฐ’์ด๋ฐ”๋กœ ๋ฐ”๋€Œ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋ฅผ ๊ฐ์ฒด ๋Œ€์‹ ์— ํ•จ์ˆ˜๋ฅผ setState ์˜ ์ธ์ž๋กœ ๋„ฃ์–ด์คŒ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

onClick={() => {  this.setState(prevState => ({    number: prevState.number + 1  }));  this.setState(prevState => ({    number: prevState.number + 1  }));}}

์ด๋ ‡๊ฒŒ setState ์˜ ์ธ์ž๋กœ ํ•จ์ˆ˜๋กœ ๋„ฃ์–ด์ฃผ๋ฉด 2์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


this.setState ๊ฐ€ ๋๋‚œ ํ›„ ํŠน์ • ์ž‘์—… ์‹คํ–‰ํ•˜๊ธฐ#

setState ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜์—ฌ setState ๊ฐ€ ๋๋‚œ ํ›„ํŠน์ • ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

<button    onClick={() => {        this.setState(            (prevState) => ({                number: prevState.number + 1,            }),            () => {                console.log('setState๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');            },        );    }}>    +1</button>

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

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

src ๋””๋ ‰ํ† ๋ฆฌ์— Say.js ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

Say.js

import React, {useState} from 'react';
const Say = () => {    const [message, setMessage] = useState('');    const onClickEnter = () => setMessage('Hi!');    const onClickLeave = () => setMessage('Bye!');
    return (        <div>            <button onClick={onClickEnter}>Enter</button>            <button onClick={onClickLeave}>Exit</button>            <h1>{message}</h1>        </div>    );};
export default Say;

์ฝ”๋“œ ์ฒซ ์ค„์„ ๋ณด๋ฉด useState ๋ฅผ import ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  useState ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ , ํ•จ์ˆ˜์˜ ์ธ์ž์—๋Š” ์ƒํƒœ์˜ ์ดˆ๊นƒ๊ฐ’์„ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ state ์ดˆ๊นƒ๊ฐ’์€ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•˜์ง€๋งŒ, useState ์—์„œ ๊ฐ’์˜ ํ˜•ํƒœ๋Š” ์ž์œ ์ด๋‹ค.

ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฐฐ์—ด์ด ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ, ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋Š” ํ˜„์žฌ ์ƒํƒœ, ๋‘ ๋ฒˆ์งธ ์›์†Œ๋Š” ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ์–ด ์ฃผ๋Š” ์„ธํ„ฐ(Setter) ํ•จ์ˆ˜์ด๋‹ค. ์ด๋ฅผ ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น์œผ๋กœ message , setMessage ์— ํ• ๋‹นํ•ด ์ฃผ๊ณ  ์žˆ๋‹ค. onClickEnter ํ•จ์ˆ˜๋Š” 'Hi!' ๋ผ๋Š” ๋ฉ”์‹œ์ง€๋กœ state ๋ฅผ ์„ธํŒ…ํ•˜๋Š” ํ•จ์ˆ˜์ด๊ณ , onClickLeave ํ•จ์ˆ˜๋Š” 'Bye!' ๋ผ๋Š” ๋ฉ”์‹œ์ง€๋กœ state ๋ฅผ ์„ธํŒ…ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.


2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-3


๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด Enter, Exit ๋ฒ„ํŠผ์„ ํด๋ฆญํ•  ๋•Œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


useState ๋Š” ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒ‰์„ ๊ด€๋ฆฌํ•˜๋Š” color ๋ฅผ state ์— ์ถ”๊ฐ€ํ•œ๋‹ค.

import React, {useState} from 'react';
const Say = () => {    const [message, setMessage] = useState('');    const onClickEnter = () => setMessage('Hi!');    const onClickLeave = () => setMessage('Bye!');
    const [color, setColor] = useState('black');
    return (        <div>            <button onClick={onClickEnter}>Enter</button>            <button onClick={onClickLeave}>Exit</button>            <h1 style={{color}}>{message}</h1>            <button style={{color: 'red'}} onClick={() => setColor('red')}>                Red            </button>            <button style={{color: 'green'}} onClick={() => setColor('green')}>                Green            </button>            <button style={{color: 'blue'}} onClick={() => setColor('blue')}>                Blue            </button>        </div>    );};
export default Say;

JSX inline style ๋ฌธ๋ฒ• style={ ๊ฐ์ฒด } ์ด๋ฏ€๋กœ color ๋Š” ํ˜„์žฌ ๋ฌธ์ž์—ด. { color } ๋กœ ํ•˜๋ฉด { color : "black" } ๋กœ ๊ฐ์ฒด ํ˜•ํƒœ๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ style={{ color }} ๊ฐ€ ์˜ณ์€ ๋ฌธ๋ฒ•.


2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-4


state ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ ์‚ฌํ•ญ#

ํด๋ž˜์Šคํ˜•, ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ๋ชจ๋‘ state ์˜ ๊ฐ’์„ ๋ฐ”๊พธ์–ด์•ผ ํ•  ๋•Œ๋Š” setState ํ˜น์€ useState ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ์„ธํ„ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ์ฒ˜๋Ÿผ state ๊ฐ’์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

// ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธthis.state.number = this.state.number + 1;this.state.array = this.array.push(2);this.state.object.value = 5;
// ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธconst [object, setObject] = useState({a: 1, b: 1});object.b = 2;

์™œ๋ƒํ•˜๋ฉด ๋ฆฌ์•กํŠธ์—์„œ๋Š” state ์˜ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ , ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์„ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๋Š”๋ฐ setState (๋˜๋Š” useState ์˜ ์„ธํ„ฐ ํ•จ์ˆ˜)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ state ๊ฐ’์„์ˆ˜์ •ํ•  ๊ฒฝ์šฐ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์ฐธ์กฐ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•  ๋•Œ๋Š” ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด ์‚ฌ๋ณธ์„๋งŒ๋“ค๊ณ , ์‚ฌ๋ณธ์˜ ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•œ ํ›„, ๊ทธ ์‚ฌ๋ณธ์˜ ์ƒํƒœ๋ฅผ setState ํ˜น์€ ์„ธํ„ฐ ํ•จ์ˆ˜๋ฅผํ†ตํ•ด ์—…๋ฐ์ดํŠธ ํ•ด์•ผํ•œ๋‹ค.

// ๊ฐ์ฒดconst object = {a: 1, b: 2, c: 3};const nextObject = {...object, b: 2};
// ๋ฐฐ์—ดconst array = [    {id: 1, value: true},    {id: 2, value: true},    {id: 3, value: false},];const nextArray = array.concat({id: 4});

๊ฐ์ฒด์—์„œ๋Š” spread ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ, ๋ฐฐ์—ด์—์„œ๋Š” ๋ฐฐ์—ด ๋‚ด์žฅํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ


์ •๋ฆฌ#

2020-03-28-๋ฆฌ์•กํŠธ๋ฅผ-๋‹ค๋ฃจ๋Š”-๊ธฐ์ˆ -3์žฅ-component-image-5

props ์™€ state ๋ชจ๋‘ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋ Œ๋”๋งํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ์ง€๋งŒ, props ๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„ค์ •ํ•˜๊ณ , state ๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

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


๊ฐ™์ด ์ฝ๊ธฐ#


React.Component - React