React๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

โ—‹ React 1 - JSX

โ— JSX๋ž€?

  • React์—์„œ ์‚ฌ์šฉ๋˜๋Š” JSX const hi = <p>Hi</p>;
  • javascript๋„ HTML๋„ ์•„๋‹Œ javascript ํ™•์žฅ๋ฒ„์ „์˜ ๋ฌธ๋ฒ• syntax extension for JavaScript
  • JSX๋Š” javascript๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— .jsํŒŒ์ผ์— JSX ๋ฌธ๋ฒ•์ด ์žˆ์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด์„ํ•˜์ง€ ๋ชปํ•ด ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค. ์ด๋•Œ ๋ฐ”๋ฒจ์„ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ปดํŒŒ์ผ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค

๐Ÿ”˜ JSX element

  • HTML๋ฌธ๋ฒ•์„ JavaScript ์ฝ”๋“œ ๋‚ด๋ถ€์— ์จ์ฃผ๋ฉด ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ JSX
  • ๋ณ€์ˆ˜์— ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ๊ณ , ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธธ ์ˆ˜๋„ ์žˆ๋‹ค
const hi = <p>Hi</p>;

const myFavorite = {
  food: <li>์ƒ๋Ÿฌ๋“œ</li>,
  animal: <li>dog</li>,
  hobby: <li>programming</li>,
};


๐Ÿ”˜ JSX attribute

  • ํƒœ๊ทธ์— attribute(์†์„ฑ)์„ ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ๋Š” ํ•ญ์ƒ โ€œโ€ ์Œ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ์ฃผ๊ธฐ
  • attribute๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ์‹ค์ œ HTML์—์„œ ์“ฐ๋Š” attribute name(์†์„ฑ๋ช…)๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜! react ๊ณต์‹๋ฌธ์„œ
const hi = <p>Hi</p>;

const myFavorite = {
  food: <li>์ƒ๋Ÿฌ๋“œ</li>,
  animal: <li>dog</li>,
  hobby: <li className='list-item'>programming</li>,
};


๐Ÿ”˜ Self-Closing Tag

  • JSX์—์„œ๋Š” ์–ด๋–ค ํƒœ๊ทธ๋ผ๋„ self closing tag๊ฐ€ ํ•ญ์ƒ ๊ฐ€๋Šฅ
  • <input>๊ณผ ๊ฐ™์ด ํ•˜๋‚˜์˜ ํƒœ๊ทธ๊ฐ€ ์š”์†Œ์ธ ๊ฒฝ์šฐ์—๋Š” <input />์™€ ๊ฐ™์ด ํ•ญ์ƒ /์œผ๋กœ ๋๋‚ด์ค˜์•ผ ํ•œ๋‹ค
  • <div />์™€ <div></div>๋Š” ๊ฐ™์€ ํ‘œํ˜„

๐Ÿ”˜ Nested JSX

1. (ํ•„์ˆ˜) ์†Œ๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ๊ธฐ

  • ์ค‘์ฒฉ๋œ ์š”์†Œ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด () ์†Œ๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์ฃผ๊ธฐ!
const good = (
  <>
    {" "}
    //Fragments
    <p>hi</p>
    <p>์•ˆ๋…•!</p>
  </>
);


2. (ํ•„์ˆ˜) Fragments ํ•ญ์ƒ ํ•˜๋‚˜์˜ ํƒœ๊ทธ๋กœ ์‹œ์ž‘

  • ์ œ์ผ ์ฒ˜์Œ ์š”์†Œ๊ฐ€ sibling์ด๋ฉด ์•ˆ๋˜๋ฏ€๋กœ, ๋ฌด์กฐ๊ฑด ํ•˜๋‚˜์˜ ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์ ธ์•ผ ํ•œ๋‹ค react_Fragments

โ— Rendering

  • html ์š”์†Œ(element), ๋˜๋Š” React ์š”์†Œ ๋“ฑ์˜ ์ฝ”๋“œ๊ฐ€ ๋ˆˆ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ทธ๋ ค์ง€๋Š” ๊ฒƒ์„ ๋ Œ๋”๋ง(rendering) ์ด๋ผ๊ณ  ํ•œ๋‹ค
  • ReactDOM.render ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById("root"));



โ—‹ React 2 - Component์™€ Props

โ— Component๋ž€?

component(์ปดํฌ๋„ŒํŠธ)๋ž€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋‹จ์œ„

  • ์ปดํฌ๋„ŒํŠธ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ, ์žฌ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์ปดํฌ๋„ŒํŠธ๋Š” ํ•จ์ˆ˜๋ž‘ ๋น„์Šทํ•˜๋‹ค. ํ•จ์ˆ˜๋„ ๊ธฐ๋Šฅ์ด ๋…๋ฆฝ์ ์ด๊ณ  ์žฌ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์žˆ๊ณ  ์ปดํฌ๋„ŒํŠธ๋„ input์„ ๋ฐ›์•„์„œ return ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๐Ÿšฉ์ง‘์ค‘! React ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” input์„ props๋ผ๊ณ  ๋งํ•˜๊ณ  return์€ ํ™”๋ฉด์— ๋ณด์—ฌ์ ธ์•ผ ํ•  React์š”์†Œ๊ฐ€ return๋œ๋‹ค

โ— Component ๋งŒ๋“ค๊ธฐ

  • component๋Š” classํ˜•๊ณผ functionํ˜•์ด ์žˆ๋‹ค

๐Ÿ”˜ ํ•จ์ˆ˜๋กœ Welcome ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}


๐Ÿ”˜ class๋กœ Welcome ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ

  • class๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋ ค๋ฉด React.Component ๋ฅผ extendํ•ด์„œ ์ƒ์„ฑ
  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ render() ๋ฉ”์„œ๋“œ๋Š” ๋ฌด์กฐ๊ฑด ์ •์˜ํ•ด์•ผํ•˜๊ณ , return๋„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค
  • render() ๋ฉ”์„œ๋“œ๋Š” ๋ฌด์กฐ๊ฑด ์ •์˜ํ•ด์•ผํ•œ๋‹ค๋Š” ๋ง์€, component๋ฅผ ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์›๋ž˜ ๋” ์žˆ๋‹ค๋Š” ๋œป. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ์ค‘์—์„œ render() ๋งŒ ํ•„์ˆ˜์ด๋‹ค
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}


โ— Component ์‚ฌ์šฉ

  • function/class ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ํƒœ๊ทธ์ฒ˜๋Ÿผ <Welcome /> ์œผ๋กœ ์ž‘์„ฑ
  • component๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—” ์›ํ•˜๋Š” attribute๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ parameter๋กœ ํ•ด๋‹น attrubute๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด๊ฒƒ์„ props๋ผ๊ณ  ํ•œ๋‹ค
  • props๋Š” property์˜ ์ค„์ž„๋ง๋กœ, .(dot)์œผ๋กœ ์†์„ฑ๋ช…์— ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๊ณ , props.์†์„ฑ๋ช… ์œผ๋กœ ์†์„ฑ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค
// 1. Welcome ์ปดํฌ๋„ŒํŠธ ์ •์˜
// Welcome ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ์ธก(๋ถ€๋ชจ)์—์„œ name์ด๋ผ๋Š” attribute๋ฅผ ๋ถ€์—ฌํ–ˆ๊ณ . props.name์˜ ๊ฐ’์„ ์‚ฌ์šฉ
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// 2. App ์ปดํฌ๋„ŒํŠธ ์ •์˜
// div๋กœ ๊ฐ์‹ธ์ ธ์žˆ๊ณ ,
// <Welcome /> ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ธ๋ฒˆ ์‚ฌ์šฉ. name์ด๋ผ๋Š” attribute๋ฅผ ๋ถ€์—ฌํ–ˆ์Œ
function App() {
  return (
    <div>
      <Welcome name='Sara' />
      <Welcome name='Cahal' />
      <Welcome name='Edite' />
    </div>
  );
}

// 3. ํ™”๋ฉด์— React ์š”์†Œ ๊ทธ๋ ค์ฃผ๊ธฐ
ReactDOM.render(<App />, document.getElementById("root"));


โ— ๋” ์ž‘์€ Component๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ

  • ์žฌ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด 1์ด๋ผ๋„ ์žˆ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค



โ—‹ React 3-Component์˜ State

โ— state

state๋ž€?? ๋ง ๊ทธ๋Œ€๋กœ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ ๊ฐ’ state์™€ props๋Š” ๋‘˜ ๋‹ค object ์ด๊ณ , ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ์ •๋ณด(์ƒํƒœ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ์ ์—์„œ ์„œ๋กœ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•œ๋‹ค

  • props๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ชจ์ชฝ์—์„œ ์ „๋‹ฌํ•ด์•ผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ (parameter ์ฒ˜๋Ÿผ)
  • state๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ์ •์˜ํ•˜๊ณ  ์‚ฌ์šฉ
class Button extends React.Component {
  constructor() {
    super();

    this.state = {
      clicked: false,
    };
  }

  render() {
    return (
      <div
        className='btn'
        // onClick์‹œ this.setState๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ state๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค
        onClick={() => {
          this.setState({ clicked: !this.state.clicked });
        }}
      >
        {this.state.clicked ? "์ข‹์•„์š”" : "์‹ซ์–ด์š”"}
      </div>
    );
  }
}

ReactDOM.render(<Button />, document.getElementById("root"));


๐Ÿ”˜ constructor()

  • constructor๋Š” class์˜ instance๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํ•ญ์ƒ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜(์ƒ์„ฑ์ž)
  • ์ดˆ๊ธฐํ™”ํ•  ๊ฐ’๋“ค์„ constructor์—์„œ ์„ธํŒ…
  • super() ๋ผ๋Š” ํ‚ค์›Œ๋“œ๋Š” ๊ผญ ์ž‘์„ฑํ•„์š”!!! ๊ทธ๋ž˜์•ผ React.Component class์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋“ค(ex. render)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

โ— props์™€ state

  • this.props.type์ด โ€˜likeโ€™์ด๋ฉด like-btn์ด๋ผ๋Š” ํด๋ž˜์Šค ์†์„ฑ์ด ์ถ”๊ฐ€ ์ฝ”๋“œ๋ณด๊ธฐ



โ—‹ React 4 - React ์ปดํฌ๋„ŒํŠธ์˜ Lifecycle

  • render, componentDidMount, componentDidUpdate, componentWillUnmount ๋“ฑ์˜ ํ•จ์ˆ˜๋Š” React.Component class์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ
  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ class๋กœ ์ƒ์„ฑํ•˜๋ฉด ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ปดํฌ๋„ŒํŠธ๊ฐ€ lifecycle์— ๋”ฐ๋ผ ๊ฐ์ž์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค


โ—‹ React 5 - ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง

โ—React์—์„œ๋Š” React element์— onClick ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ event handler ํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค

class Button extends React.Component {
  constructor() {
    super();

    this.state = {
      clicked: false,
    };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
      clicked: !this.state.clicked,
    });
  }

  render() {
    return (
      <div
        className={`btn ${this.props.type === "like" ? "like-btn" : ""}`}
        onClick={this.handleClick}
      >
        {this.state.clicked ? "์ข‹์•„์š”" : "์‹ซ์–ด์š”"}
      </div>
    );
  }
}

ReactDOM.render(<Button type='like' />, document.getElementById("root"));


๐Ÿ”˜ React ์š”์†Œ์— ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ bind(this)๋ฅผ ํ•ด์ค˜์•ผํ•œ๋‹ค

  • ์ด๋ฒคํŠธ์— event handler ํ•จ์ˆ˜๋ฅผ ๋„˜๊ธธ๋•Œ bind๋ฅผ ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด event handler ํ•จ์ˆ˜๋‚ด์—์„œ this์˜ context๋ฅผ ์žƒ์–ด๋ฒ„๋ ค์„œ this๊ฐ€ undefined๊ฐ€ ๋œ๋‹ค
  • handleClick ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ this ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด this๋Š” Button ์ปดํฌ๋„ŒํŠธ์˜ context์—ฌ์•ผ ํ•œ๋‹ค
  • handleClick.bind(this)๋ผ๊ณ  ์ž‘์„ฑํ•ด์ค€ ์œ„์น˜์—์„œ ๊ทธ this๋ฅผ handleClick ์— ๋„˜๊ฒจ์„œ handleClick ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ๋„ ๊ฐ™์€ this๋ฅผ ์“ฐ๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค
  • ๊ทธ๋ž˜์•ผ๋งŒ Button ์ปดํฌ๋„ŒํŠธ์˜ this.state์— ์ ‘๊ทผํ•˜๊ณ , setState ํ•จ์ˆ˜๋„ ์“ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ

โœจ์ฐธ๊ณ โœจ context

  • context๋Š” React ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ์•ˆ์—์„œ ์ „์—ญ์ (global)์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ์•ˆ๋œ ๋ฐฉ๋ฒ• react_context