/ReactStudy

React Toy Project

Primary LanguageJavaScript

๐ŸงฉReactStudy๐Ÿงฉ

0. About Repository

React๋ฅผ ์ฒ˜์Œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์‹œ๋„ํ–ˆ๋˜ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ž‘์€ ํ”„๋กœ์ ํŠธ์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋‹ด์€ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค.
์•„๋ž˜๋Š” ์ƒํ™œ์ฝ”๋”ฉ ๋ฆฌ์•กํŠธ ๊ธฐ์ดˆ ๊ฐ•์ขŒ๋ฅผ ๋“ค์œผ๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

1. About React

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ•˜๋‚˜๋กœ์จ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.
๊ฐ€์žฅ ํฐ ํŠน์ง•์€ ์‚ฌ์šฉ์ž ์ •์˜ ํƒœ๊ทธ(์ปดํฌ๋„ŒํŠธ)๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ์ˆ ์ด๋ผ๋Š” ๊ฒƒ.

(1) ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ์žฅ์ 

  • ๊ฐ€๋…์„ฑ์ด ๋†’์Œ(ํƒœ๊ทธ๋ช…๋งŒ์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ ๊ฐ€๋Šฅ)
  • ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์Œ
  • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›€

(2) JSX

  • JSX ๋ฌธ๋ฒ•์—๋„ ์ต์ˆ™ํ•ด์ ธ์•ผ ํ•œ๋‹ค! ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์„ ๋•Œ๋Š” ์ค‘๊ด„ํ˜ธ{} ์•ˆ์— ๋‹ด์•„์•ผ ํ•จ์„ ๊ธฐ์–ตํ•˜์ž.

(3) ์‹คํ–‰ ๋ฐ ๋ฐฐํฌ

  • ๋กœ์ปฌ์—์„œ ์‹คํ–‰ ํ™”๋ฉด์„ ํ™•์ธํ•  ๊ฒฝ์šฐ : npm run start ์‚ฌ์šฉ
  • ๋ฐฐํฌํ•  ๊ฒฝ์šฐ : npm run build ์‚ฌ์šฉ(๋ฌด์˜๋ฏธํ•œ ๊ณต๋ฐฑ ๋“ฑ์„ ์—†์•  ์šฉ๋Ÿ‰์„ ์ตœ์†Œํ•œ์œผ๋กœ ์ค„์ž„)

(4) ๊ฐ€์ƒ ๋”

  • Document Object Model : ๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ(HTML ๋‹จ์œ„ ํ•˜๋‚˜ํ•˜๋‚˜๋ฅผ ๊ฐ์ฒด๋กœ ์ƒ๊ฐํ•œ ๋ชจ๋ธ)
  • ๋ Œ๋”ํŠธ๋ฆฌ๊ฐ€ ๋งค๋ฒˆ ์žฌ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์Œ. ๋”ฐ๋ผ์„œ ๊ฐ€์ƒ ๋”์€ ๋ณ€ํ™”๋ฅผ ๊ฐ€์ƒ ๋”์—์„œ ๋ฏธ๋ฆฌ ์ธ์ง€ํ•ด ๋ณ€ํ™”์‹œํ‚ด.
  • ์ด ์ž‘์—…์€ ์‹ค์ œ DOM ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋žœ๋”๋ง๋˜์ง€ ์•Š๊ณ  ์—ฐ์‚ฐ ๋น„์šฉ์ด ์‹ค์ œ DOM๋ณด๋‹ค๋Š” ์ ์Œ.
  • ์ด ๊ฐ€์ƒ DOM์˜ ๋ณ€ํ™”๋ฅผ ๋งˆ์ง€๋ง‰์— ์‹ค์ œ DOM์—๊ฒŒ ๋˜์ ธ์ฃผ์–ด, ๋ชจ๋“  ๋ณ€ํ™”๋ฅผ ํ•œ ๋ฒˆ์— ๋žœ๋”๋ง ๋˜๊ฒŒ ํ•จ.
  • ์ฆ‰, ๊ฐ€์ƒ ๋”์€ ๋ฐ”๋€Œ์ง€ ์•Š์€ ๋ถ€๋ถ„๊ณผ ๋ฐ”๋€ ๋ถ€๋ถ„์„ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•ด์„œ ์—…๋ฐ์ดํŠธ ์‹œ์ผœ์ค€๋‹ค๋Š” ๋ง์ธ๋ฐ...
  • ์‚ฌ์‹ค ์ƒํ™œ์ฝ”๋”ฉ์—์„œ DOM์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ๋‹ค๋ฃจ์ง€ ์•Š์•„์„œ ๋ฌด์Šจ ๋ง์ธ์ง€ ์ •ํ™•ํžˆ๋Š” ๋ชจ๋ฅด๊ฒ ์Œ. ๋” ์ฐพ์•„๋ณด๊ธฐ.

(5) ํด๋” ๊ตฌ์กฐ

    ReactStudy
        |
        | - public : ๊ฐ€์ƒ DOM์ด ๋“ค์–ด๊ฐ„ ๋นˆ ๊ป๋ฐ๊ธฐ(?) html์ด ์กด์žฌํ•˜๋Š” ํด๋”
        | - src : ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๋ฉ”์ธ ํด๋”

public/manifest.json : ์›น ์•ฑ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์„ ๋ณผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ์˜์—ญ์— ์›น ์•ฑ์ด๋‚˜ ์‚ฌ์ดํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฉ์‹์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ์–ดํ•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์„ ์ง€์‹œํ•˜๊ณ , ์‹œ์ž‘ ์‹œ์˜ ๋ชจ์Šต์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” JSON ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.(๊ตฌ๊ธ€์—์„œ ์ •์˜ํ•œ ๋‚ด์šฉ)

(6) render?

  • ํ™”๋ฉด์— html ๋ทฐ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•จ
  • return์œผ๋กœ ๋ฐ›๋Š” ๊ฐ’๋“ค์€ ๋‚˜์ค‘์— html ์ฝ”๋“œ๋กœ ๋ฐ”๋€๋‹ค.

(7) ํ•จ์ˆ˜ํ˜•๊ณผ ํด๋ž˜์Šคํ˜•

  • ์ƒํ™œ์ฝ”๋”ฉ์—์„œ๋Š” ํด๋ž˜์Šคํ˜•์„ ์‚ฌ์šฉํ•ด ๊ฐ•์˜๋ฅผ ์ง„ํ–‰ํ–ˆ์Œ.

(8) LifeCycle

๋‚˜์ค‘์— ๋ฆฌ์•กํŠธ์— ์–ด๋Š์ •๋„ ์ต์ˆ™ํ•ด์ง€๋ฉด ์ฐพ์•„๋ณด๊ธฐ. ์ง€๊ธˆ์€ ๋ฆฌ์•กํŠธ๋ž‘ ์นœํ•ด์ง€๋Š”๊ฒŒ ๋จผ์ €!



2. Component

(1) ๊ธฐ๋ณธ ์ •์˜

class Subject extends Component {
   render() {
      return (
        <header> //์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ํ•˜๋‚˜์˜ ์ตœ์ƒ์œ„ ํƒœ๊ทธ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
          <h1> ํƒ€์ดํ‹€ </h1>
          ๋‚ด์šฉ์ด ์–ด์ฉŒ๊ตฌ ์ €์ฉŒ๊ตฌ
        </header>
      );
   }
}

class App extends Component {
  render() {
    return (
      <div className = "App">
        <Subject></Subject>   //์ด๋Ÿฐ ์‹์œผ๋กœ ์ž„์˜์˜ ํƒœ๊ทธ๋ฅผ ์ •์˜ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ถ€๋ถ„์— ์œ„์— ์ž‘์„ฑํ•œ Subject์˜ ์ฝ”๋“œ๊ฐ€ ์ ์šฉ๋œ๋‹ค.
      </div>
    );
  }
}

export default App;

(2) ํŒŒ์ผ์˜ ๋ถ„๋ฆฌ

๋ผ์šฐํŒ…์ด๋ž‘ ๋น„์Šทํ•œ ๊ฐœ๋…์ธ ๋“ฏ. Subject.js ํŒŒ์ผ์— Subject ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ฒจ๋†“๊ณ  App.js์—์„œ ํ•ด๋‹น ๊ฒฝ๋กœ๋ฅผ importํ•ด์ฃผ๋ฉด App์—์„œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

import Subject from "./components/Subject";

๋‹จ ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•  ๊ฒฝ์šฐ Subject ์ฝ”๋“œ์— ํ•„์š”ํ•œ ์š”์†Œ๋“ค์€ Subject.js์—์„œ ๋ชจ๋‘ import ํ•ด์ฃผ์–ด์•ผ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๋Š”๋‹ค.



3. State & Props

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

props

๋‚ด๋ถ€์ ์œผ๋กœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋‚˜ ์ƒํƒœ๋Š” state๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•œ๋‹ค.
props์™€ state ๋ชจ๋‘ render ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์œ ๋„ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, UI๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•ด์•ผ ํ•œ๋‹ค.
props์˜ read-only์˜ ์˜๋ฏธ : ์‚ฌ์šฉํ•˜๋Š” ์ชฝ์—์„œ๋Š” props๋ฅผ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ๋Š” ์ „๋‹ฌ ๋ฐ›์€ props์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.
์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ state๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ๋Š” props ์‚ฌ์šฉ
ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ state๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ๋Š” event ์‚ฌ์šฉ
์™ธ๋ถ€์—์„œ๋Š” props๋ฅผ ํ†ตํ•ด์„œ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ state๋ฅผ ์ œ์–ด
์ปดํฌ๋„ŒํŠธ๋Š” props์™€ state์˜ ์˜ํ–ฅ์— ๋”ฐ๋ผ์„œ ์‹ค์ œ DOM์— ์˜ํ–ฅ์„ ์ค˜ UI๊ฐ€ ๊ทธ๋ ค์ง


(1) constructor

component๊ฐ€ ์‹คํ–‰๋  ๋•Œ, render ํ•จ์ˆ˜๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜๋ฉด์„œ component๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์‹ถ์„ ๋•Œ constructor๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

class App extends Component {
  constructor(props){ //props๋ฅผ ํ™œ์šฉ(๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค๋ฅธ ๋‚ด์šฉ์œผ๋กœ ์žฌ์‚ฌ์šฉ)
    super(props);
    this.state = {
      subject:{title:'WEB', sub:'World Wide Web!'},  //์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€ ์ •๋ณด๊ฐ€ ๋ณด์ด์ง€ ์•Š๋„๋ก ์€๋‹‰ํ•˜๋Š” ๊ฒƒ์ด ์žฌ์‚ฌ์šฉ์„ฑ์˜ ํ•ต์‹ฌ
      //์—ฌ๋Ÿฌ๊ฐœ์˜ state๋ฅผ ์ •์˜ํ•  ๊ฒฝ์šฐ ๋ฐฐ์—ด ์‚ฌ์šฉ
      content:[
        {id : 1, title:'HTML', desc:'HTML is for information'},
        {id : 2, title:'CSS', desc:'CSS is for design'},
        {id : 3, title:'Javascript', desc:'Javascript is for interactive'}
      ]
    }
  }

(2) ๋ถ€๋ชจ -> ์ž์‹ ๊ฐ’ ์ „๋‹ฌ

์œ„์—์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ state ๊ฐ’์„ ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ props ๊ฐ’์œผ๋กœ ์ „๋‹ฌ ๊ฐ€๋Šฅ

  render() {
    return (
      <div className = "App">
        <Subject
          title = {this.state.subject.title}  //๋ฌธ์ž๊ฐ€ ์•„๋‹Œ ์ฝ”๋“œ๋กœ ์ธ์‹๋˜๋ ค๋ฉด ํฐ๋”ฐ์˜ดํ‘œ ๋ง๊ณ  ์ค‘๊ด„ํ˜ธ ์‚ฌ์šฉ
          sub = {this.state.subject.sub}>
        </Subject>
        <TOC data={this.state.contents}></TOC>
        <Content title = "HTML" desc = "์ด๊ฒŒ๋˜๋„ค..์‹ ๊ธฐํ•˜๋„ค"></Content>
      </div>
    );
  }
}

(3) key

์—ฌ๋Ÿฌ ๊ฐœ์˜ elements๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ (Warning: Each Child in a list should have a unique "key" prop.)

class TOC extends Component {
  render() {
    var lists = [];
    var data = this.props.data;
    var i =0;

    //์ž„์˜๋กœ element๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •
    while(i < data.length){
      //react๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์น˜์ธ key๋ฅผ ํ•„์š”๋กœํ•จ.
      lists.push(<li key={data[i].id}><a href = {"/content/"+data[i].id}>{data[i].title}</a></li>);
      i = i+1;
    }

    return (
      <nav>
        <ul>
          {lists}
        </ul>
      </nav>
    );
  }
}

(4) ๊ฐ’์ด ๋ฐ”๋€” ๊ฒฝ์šฐ

ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ state ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด ๊ทธ state๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ renderํ•จ์ˆ˜๊ฐ€ ์žฌํ˜ธ์ถœ๋จ. (์•„๋ž˜ ์ด๋ฒคํŠธ์—์„œ ์ด ํŠน์ง•์„ ํ™œ์šฉํ•จ.)



4. EVENT

(1) onClick

ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ณ€ํ™”๋ฅผ ์ฃผ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ onClick ์•ˆ์— ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด ์›ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

<header>
  <h1><a href = "/" onClick={function(e){
    e.preventDefault(); //ํŽ˜์ด์ง€ ์ „ํ™˜ ๋ง‰๊ธฐ : a ํƒœ๊ทธ์˜ ๊ธฐ๋ณธ์ ์ธ ๋™์ž‘ ๋ฐฉ๋ฒ•์„ ๊ธˆ์ง€
    this.setState({
      mode: 'welcome'
    });
  }, bind(this)}>{this.state.subject.title}</a></h1>
</header>

์ด๋ฏธ ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ์ด ๋๋‚œ ํ›„์— ๋™์ ์œผ๋กœ state ๊ฐ’์„ ๋ฐ”๊พธ๊ณ ์ž ํ•  ๋•Œ๋Š” this.state.์–ด์ฉŒ๊ตฌ = '์–ด์ฉŒ๊ตฌ'๋กœ ๋ฐ”๊พธ๋ฉด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— setState ์‚ฌ์šฉ
this.state.mode = 'welcome'์œผ๋กœ ํ•˜๋ฉด ๋ฆฌ์•กํŠธ์—์„œ state๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ด์„œ render๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Œ


(2) bind ํ•จ์ˆ˜

render ํ•จ์ˆ˜ ์•ˆ์—์„œ this๋Š” ๊ทธ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๊ทธ ์ž์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ, function ์•ˆ์—์„œ์˜ this๋Š” ์•„๋ฌด ๊ฐ’๋„ ๊ฐ€๋ฆฌํ‚ค์ง€ ์•Š๋Š”๋‹ค.(undefined)
function ๋‚ด๋ถ€์—์„œ ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋ฅผ this๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๊ฐ€ bind ํ•จ์ˆ˜์ด๋‹ค.

var obj = {'name' : '์ด๋ฆ„'}

function bindTest() {
  console.log(this.name);
}

var bindTest2 = bindTest.bind(obj);

ํ•  ๊ฒฝ์šฐ bind ํ•จ์ˆ˜์— ์˜ํ•ด obj๊ฐ€ bindTest()์˜ this๊ฐ€ ๋˜๋Š” ์›๋ฆฌ.

cf) ํฅ๋ฏธ๋กœ์šด ์  : bind(a, b)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ b์˜ ๊ฐ’์ด ํ•ด๋‹น function์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž ๊ฐ’์— ๋“ค์–ด๊ฐ„๋‹ค.

data-id = {data[i].id}
onClick = {function(e){
  e.preventDefault();
  this.props.onChangePage(e.target.dataset.id);
  }, bind(this)
}

onClick = {function(id, e){
  e.preventDefault();
  this.props.onChangePage(e.target.dataset.id);
  }, bind(this, data[i].id)
}

์œ„์˜ ๋‘ ํ•จ์ˆ˜๋Š” ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

(3) ์ž„์˜์˜ ์ด๋ฒคํŠธ ์ƒ์„ฑ

App.js์—์„œ ์ •์˜ํ•œ onChangePage๋ผ๋Š” ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ js ํŒŒ์ผ์—์„œ ์ ์šฉํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ props๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ€์ ธ์˜ค๋ฉด ๋œ๋‹ค.

1) App.js

  <Subject
    title = {this.state.subject.title}
    sub={this.state.subject.sub}
    onChangePage = {function(){
      this.setState({
      mode: 'welcome'
      });
    }.bind(this)}
  >
  </Subject>


2) Subject.js

  onClick = {function(e){
    e.preventDefault();
    this.props.onChangePage(e.target.dataset.id);
    }
  }

๋ฌด์—‡์ด ํด๋ฆญ๋˜๋ƒ์— ๋”ฐ๋ผ ๋‚˜ํƒ€๋‚˜๋Š” ๋‚ด์šฉ์ด ๋ฐ”๋€Œ๋Š” ํŽ˜์ด์ง€์—ฌ์„œ ํด๋ฆญ๋˜๋Š” ์š”์†Œ์˜ id ๊ฐ’์ด ํ•„์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— e.target.dataset.id๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.



5. CRUD๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ๋œ ๊ธฐํƒ€ ๊ฐœ๋…์— ๋Œ€ํ•˜์—ฌ

(1) CREATE ํ–ˆ์„ ๋•Œ ํ™”๋ฉด์— ์ƒˆ๋กœ์šด ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ

  1) onSubmit ์ด๋ฒคํŠธ์—์„œ e.target์„ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์„ props๋กœ ๋ณด๋ƒ„

  <form action="/create_process" method="post"
    onSubmit={function(){
      e.preventDefault();
      this.props.onSubmit(
        e.target.title.value,
        e.target.desc.value
      );
    }.bind(this)}
  >


  2) App.js์—์„œ๋Š” onSubmit ์ด๋ฒคํŠธ์— e.target.title.value์™€ e.target.desc.value๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์™€ state ๋ณ€๊ฒฝ

  _article = <CreateContent onSubmit={function(_title, _desc){
    // add content to this.state.contents
    
    this.max_content_id = this.max_content_id+1;
    
    var _content = this.state.contents.concat(
      {id:this.max_content_id, title:_title, desc:_desc}
    )
    
    this.setState({
      contents:_content
    });

  }.bind(this)}></CreateContent>

์ƒˆ๋กœ ์ž…๋ ฅ๋ฐ›์€ ์š”์†Œ๋“ค์„ concat์œผ๋กœ ์ถ”๊ฐ€ํ•ด์„œ ํ™”๋ฉด์— ๋ณด์—ฌ์คŒ.


(2) shouldComponentUpdate

render ์ด์ „์— ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋กœ, ์—ฌ๊ธฐ์„œ '๋ณ€ํ™”'๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์›๋ณธ์„ ๋ฐ”๊พธ์ง€ ์•Š๊ณ (push) ์‚ฌ๋ณธ์„ ์ˆ˜์ •ํ–ˆ๋‹ค.(concat)

    //render ์ด์ „์— ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜
    shouldComponentUpdate(newProps, newState){  //์ƒˆ๋กญ๊ฒŒ ๋ฐ”๋€ ๊ฐ’๊ณผ ์ด์ „ ๊ฐ’์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
      if(this.props.data === newProps.data){
        return false;
      }else{
        return true;//return๊ฐ’์ด true์ด๋ฉด render๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ , false๋ฉด ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.
      }
    }

Array.from()์„ ์‚ฌ์šฉํ•ด ์‚ฌ๋ณธ์„ ๋งŒ๋“  ํ›„ pushํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.


(3) ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง

์ค‘๋ณตํ•ด์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋“ค์€ ๋”ฐ๋กœ ์ •์˜ํ•ด๋†“๊ฑฐ๋‚˜ ๋ฏธ๋ฆฌ ์ดˆ๊ธฐํ™”ํ•ด๋‘๋ฉด ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง„๋‹ค.

    constructor(props){
      super(props);
      this.state = {
        title:this.props.data.title
      }

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

    inputFormHandler(e){
      this.setState({[e.target.name]:e.target.value});
    }

    ์ด๋ ‡๊ฒŒ ์œ„์— ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘๋ฉด render์—์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    <p>
      <input
        type="text"
        name="title"
        placeholder="title"
        value = {this.props.data.title}
        onChange={this.inputFormHandler}
      >
      </input>
    </p>