React ๊ธฐ๋ณธ


๐Ÿฆย ๋ฆฌ์•กํŠธ ๊ด€๋ จ ๊ฐœ๋…

JSX

  • JS์— XML์„ ์ถ”๊ฐ€ํ•œ ๋ฌธ๋ฒ•
  • ๋ณดํ†ต ๋ฆฌ์•กํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ
  • HTML ๋ฌธ์„œ ๊ตฌ์กฐ๋ฅผ JS์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.
  • ๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฅผ ์ฝ๊ธฐ ์œ„ํ•ด์„œ๋Š” Babel์ด๋ผ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•„์š”!
  • Babel

  • JS์˜ ์ปดํŒŒ์ผ๋Ÿฌ
  • ๊ณผ๊ฑฐ ES6๊ฐ€ ๋‚˜์˜ค๊ณ  ๋ช‡๋ช‡ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ES6๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ES5 ๋ฌธ๋ฒ•์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋˜ ๊ธฐ๋Šฅ์„ ํ–ˆ์Œ
  • ์š”์ฆ˜์€ ์ด๋Ÿฌํ•œ ์—ญํ• ์€ ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ์ถ”๊ฐ€์ ์ธ ์–ธ์–ด๋“ค์— ๋Œ€ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ ์—ญํ• ์„ ํ•œ๋‹ค.
  • Webpack

  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ํ•ฉ์ณ์ฃผ๋Š” ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(Module Bundler)
  • ์›น ๊ฐœ๋ฐœ์— ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๊ธฐ ์‹œ์ž‘ํ•˜๋‹ˆ ์šฉ๋Ÿ‰ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด Webpack์ด๋‹ค.
  • ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ํ•„์š”ํ•œ ์ˆœ๊ฐ„์— ๋ชจ๋“ˆ ํ˜•ํƒœ๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉ์„ ํ•˜๊ณ , ๋ฐฐํฌํ•  ๋•Œ์—๋Š” ํ•„์š” ์—†๋Š” ๊ธฐ๋Šฅ์€ ๋‹ค ๋นผ๊ณ  ๋นŒ๋“œ๋ฅผ ํ•˜๋Š” ๊ฒƒ์„ ๋„์™€์ค€๋‹ค.
  • ์˜์กด์„ฑ์ด ์žˆ๋Š” ๋ชจ๋“ˆ์„ ๋ชจ์•„์„œ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.
  • ๐Ÿง‡ย Component

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

    import React, {Component} from 'react';
    class ClassComponent extends Component {
    render() {
    return(
    <h1>Class Component ์ž…๋‹ˆ๋‹ค.</h1>
    );
    }
    }
    export default ClassComponent;
  • ์ตœ์ดˆ์— ์‚ฌ์šฉ๋˜์—ˆ๋˜ ์ปดํฌ๋„ŒํŠธ
  • ์ปดํฌ๋„ŒํŠธ ์ž์ฒด๊ฐ€ JS์˜ Class์™€ ์œ ์‚ฌํ•˜๋‹ค.
  • state์™€ ๋ผ์ดํ”„ ์‚ฌ์ดํด์ด๋ผ๋Š” ๋ฆฌ์•กํŠธ์˜ ์žฅ์ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ์ž์›๋„ ๋” ํ•„์š”ํ•˜๊ณ  ๋А๋ฆฌ๋‹ค.
  • render๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
  • ์ตœ๊ทผ์—๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ถ”์„ธ์ด๋‹ค.
  • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ

    const FunctionComponent = () => {
    return <div>Funtional Component ์ž…๋‹ˆ๋‹ค</div>
    };
    export default FunctionComponent;
  • ๊ตฌ์กฐ ์ž์ฒด๊ฐ€ ํด๋ž˜์Šค์— ๋น„ํ•ด ๋‹จ์ˆœํ•˜๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ๋„ ์ž์›๋„ ๋œ ํ•„์š”ํ•˜๊ณ  ๋น ๋ฅด๋‹ค.
  • ๊ณผ๊ฑฐ์—๋Š” state์™€ ๋ผ์ดํ”„์‚ฌ์ดํด ๊ธฐ๋Šฅ ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์ง€๋งŒ ์ตœ๊ทผ์—๋Š”(16๋ฒ„์ „๋ถ€ํ„ฐ) Hooks๋ผ๋Š” ๊ธฐ๋Šฅ์˜ ๋„์ž…์œผ๋กœ ๊ฐ™์€ ์—ญํ• ์˜ ์ˆ˜ํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๐Ÿฅจย JSX ๋ฌธ๋ฒ•

    ClassName

  • JS์— ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ํ‹€์˜ Class๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— JSX์—์„œ๋Š” DOM ์š”์†Œ์— class๋ฅผ ๋ถ€์—ฌํ•  ๋•Œ className์ด๋ผ๊ณ  ์จ์•ผํ•œ๋‹ค.
  • function App() {
    const str = 'Hello, JSX World!'
    return (
    <div className="App">
    {str}
    </div>
    );
    }
    export default App;

    { } ์ค‘๊ด„ํ˜ธ

  • {} ์•ˆ์— JS ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • function App() {
    const str = 'Hello, JSX World!'
    return (
    <div className="App">
    {str}
    </div>
    );
    }
    export default App;

    Inline Style ์ ์šฉ

  • ์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋•Œ์—๋„ {}๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.
  • JS๋ฌธ๋ฒ•์„ ์“ฐ๊ฒ ๋‹ค๋Š” {} ์•ˆ์— ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • function App() {
    return (
    <div className="App">
    <div style={{ fontSize: "32px" }}>์ธ๋ผ์ธ ์Šคํƒ€์ผ</div>
    </div>
    );
    }
    export default App;
  • ๋ณ€์ˆ˜(๊ฐ์ฒด)๋กœ ์„ ์–ธํ•ด์„œ ์ „๋‹ฌํ• ์ˆ˜๋„ ์žˆ๋‹ค.
  • function App() {
    const fontStyle = { fontSize: "32px" }
    return (
    <div className="App">
    <div style={fontStyle}>์ธ๋ผ์ธ ์Šคํƒ€์ผ</div>
    </div>
    );
    }
    export default App;

    kebab-case โ†’ camelCase

  • JS์—์„œ - ๋Š” ๋นผ๊ธฐ์˜ ์˜๋ฏธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ์กด kebab-case๋กœ ํ‘œํ˜„ํ•˜๋˜ ๊ฒƒ์„ camelCase๋กœ ํ‘œํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ด๋Š” style ๋˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ •ํ•  ๋•Œ ์ ์šฉํ•œ๋‹ค.
  • function App() {
    return (
    <div className="App">
    <div style={{ fontSize: "32px", backgroundColor: "orange" }}>์ธ๋ผ์ธ ์Šคํƒ€์ผ</div>
    </div>
    );
    }
    export default App;
  • ex) font-size โ†’ fontSize,
  • EventListener

  • ๋ฆฌ์•กํŠธ์—์„œ๋Š” ์—ฌ๊ธฐ์„œ๋„ camelCase๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • onclick โ†’ onClick
  • onClick = { ํด๋ฆญ ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  JS ์ฝ”๋“œ }
  • function EventHandler() {
    return (
    <span
    onClick={() => {
    console.log('ํด๋ฆญ๋จ!');
    }}
    >
    ํด๋ฆญ!
    </span>
    );
    }
    export default EventHandler;
  • ์œ„์ฒ˜๋Ÿผ () โ‡’ ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ”๋กœ ์‹คํ–‰๋˜์–ด๋ฒ„๋ฆฐ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์œ„์ฒ˜๋Ÿผ ์ต๋ช…ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋กœ ์„ ์–ธํ•ด์„œ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • function EventHandler() {
    function printConsole() {
    console.log('ํด๋ฆญ๋จ!');
    }
    return <span onClick={printConsole}>ํด๋ฆญ!</span>;
    }
    export default EventHandler;
  • ์—ฌ๊ธฐ์„œ๋„ ํ•จ์ˆ˜๋ช… ๋’ค์— ()๋ฅผ ๋ถ™์ด๊ฒŒ ๋˜๋ฉด ๋ฐ”๋กœ ์‹คํ–‰์ด ๋˜์–ด๋ฒ„๋ฆฐ๋‹ค.
  • ๐Ÿˆย State

  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ€์ง€๋Š” ์ƒํƒœ
  • JS์˜ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • useState

  • useState๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด import ํ•ด์•ผ ํ•œ๋‹ค.
  • import { useState } from 'react';
  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์—ฌ state์™€ setState๋ฅผ ์„ ์–ธํ•ด์ค€๋‹ค.
  • const [state, setState] = useState(์ดˆ๊ธฐ๊ฐ’);
  • useState๋Š” state๊ฐ€ ์ด์ „์˜ ๊ฐ’๊ณผ ๋‹ฌ๋ผ์ง€๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋งŒ์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค.
  • ์˜ˆ์‹œ๋กœ ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • import { useState } from 'react';
    export default function State() {
    const [name, setName] = useState('์žฅ๊ฒฝ์€');
    const convertLang = () => {
    name === '์žฅ๊ฒฝ์€' ? setName('JKE') : setName('์žฅ๊ฒฝ์€');
    };
    return (
    <div>
    <button onClick={convertLang}>ํ•œ/์˜ ๋ณ€ํ™˜!</button>
    <div>{name}</div>
    </div>
    );
    }

    State์™€ ๋ณ€์ˆ˜

    import { useState } from 'react';
    export default function StateAndVar() {
    const [state, setState] = useState(0);
    let a = 0;
    function plus() {
    a++;
    console.log(`state: ${state}, variable: ${a}`);
    }
    return (
    <div>
    <h1>
    {state} / {a}
    </h1>
    <button
    onClick={() => {
    setState((cur) => cur + 1);
    plus();
    }}
    >
    +1
    </button>
    </div>
    );
    }
  • state ๊ฐ’์ด ๋ณ€ํ˜•๋˜๋ฉด state๋ฅผ ์ •์˜ํ•œ ํ•จ์ˆ˜(์ปดํฌ๋„ŒํŠธ)๊ฐ€ ๋‹ค์‹œ ๋žœ๋”๋ง๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ state๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค let a = 0์ด๋ผ๊ณ  ์„ ์–ธํ•œ ์ฝ”๋“œ๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜์–ด ๋ณ€์ˆ˜ a๋Š” ++๋ฅผ ํ•ด์ฃผ๋”๋ผ๋„ 0๊ณผ 1์— ๋จธ๋ฌผ๊ฒŒ ๋œ๋‹ค. (console ์—๋Š” ์ง์ „์— +1 ํ•ด์ฃผ์—ˆ์œผ๋ฏ€๋กœ 1๋กœ ์ฐํž˜)
  • State์™€ Reference Type

    import { useState } from 'react';
    export default function StateProblem() {
    const [state, setState] = useState([0]);
    console.log(state);
    return (
    <div>
    {state}
    <br />
    <button
    onClick={() => {
    state[0] = 1;
    setState(state);
    console.log(state);
    }}
    >
    1๋กœ ๋งŒ๋“ค๊ธฐ
    </button>
    </div>
    );
    }
  • ์œ„ ์ฝ”๋“œ์—์„œ 1๋กœ ๋งŒ๋“ค๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋„ ์ฝ˜์†”์—๋Š” [1]์ด ์ฐํžˆ์ง€๋งŒ ์ˆซ์ž 0์ด 1๋กœ ๋žœ๋”๋ง๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.
  • ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
  • ๋žœ๋”๋ง๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”?
  • import { useState } from 'react';
    export default function StateProblem() {
    const [state, setState] = useState([0]);
    console.log(state);
    return (
    <div>
    {state}
    <br />
    <button
    onClick={() => {
    setState([1]);
    console.log(state);
    }}
    >
    1๋กœ ๋งŒ๋“ค๊ธฐ
    </button>
    </div>
    );
    }
  • ์œ„ ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๋ฉด [1]์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ state์— ์„ธํŒ…ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์†Œ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด ๋žœ๋”๋ง ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • import { useState } from 'react';
    export default function StateProblem() {
    const [state, setState] = useState([0]);
    console.log(state);
    return (
    <div>
    {state}
    <br />
    <button
    onClick={() => {
    state[0] = 1;
    const copyArr = [...state];
    setState(copyArr);
    console.log(state);
    }}
    >
    1๋กœ ๋งŒ๋“ค๊ธฐ
    </button>
    </div>
    );
    }
  • ๋˜๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•ด๋„ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์ด ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์†Œ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์ด๋‹ค. (๋žœ๋”๋ง์ด ๋œ๋‹ค.)
  • ๋”ฐ๋ผ์„œ ๋ฐฐ์—ด ๋˜๋Š” ๊ฐ์ฒด๋กœ State ๊ฐ’์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ด๊ฒƒ์ด JS์˜ Reference Type์ด๋ผ๋Š” ๊ฒƒ์„ ์—ผ๋‘์— ๋‘๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ๐Ÿฅƒย Props

  • properties์˜ ์ค„์ž„๋ง
  • ์–ด๋– ํ•œ ๊ฐ’์„ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ด์•ผ ํ•  ๋•Œ, props๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ž์‹ ์ž…์žฅ์—์„œ๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.
  • ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

    function PropsHeader({ text }) {
    return <h1>{text}</h1>;
    }
    export default PropsHeader;
  • Props๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋“ฏ์ด ์ „๋‹ฌํ•˜๋ฉด ๋œ๋‹ค.
  • import PropsHeader from './components/PropsHeader';
    function App() {
    return (
    <div className='App'>
    <PropsHeader text='์•ˆ๋…•ํ•˜์„ธ์š”' />
    <PropsHeader text='๊ฐ์‚ฌํ•ด์š”' />
    <PropsHeader text='์ž˜์žˆ์–ด์š”' />
    <PropsHeader text='๋‹ค์‹œ๋งŒ๋‚˜์š”' />
    </div>
    );
    }
    export default App;
  • ์ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
  • ์—ฌ๊ธฐ์„œ๋Š” ๋ฌผ๋ก  ์—ฌ๋Ÿฌ ๊ฐœ์˜ Props๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ Props ์ „๋‹ฌ