Skip to content

Latest commit

ย 

History

History
165 lines (128 loc) ยท 5.72 KB

File metadata and controls

165 lines (128 loc) ยท 5.72 KB

๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ†ตํ•ฉํ•˜๊ธฐ

React ์•ฑ ์•ˆ์— ๋‹ค๋ฅธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์–ผ๋งˆ๋“ ์ง€ ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

DOM ์กฐ์ž‘ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ํ†ตํ•ฉํ•˜๊ธฐ

React๋Š” React์˜ ์™ธ๋ถ€ DOM์—์„œ ์ผ์–ด๋‚˜๋Š” ๋ณ€ํ™”๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฐ™์€ DOM ๋…ธ๋“œ๋ฅผ ๋‹ค๋ฃฌ๋‹ค๋ฉด ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฒƒ์ด๋‹ค. ์ด ์ถฉ๋Œ์„ ํ”ผํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๊ฒŒ ๋ง‰๋Š” ๊ฒƒ์ด๋‹ค.

jQuery ํ”Œ๋Ÿฌ๊ทธ์ธ

jQuery ํ”Œ๋Ÿฌ๊ทธ์ธ์ด DOM์˜ ์ผ๋ถ€์— ์ž์œ ๋กญ๊ฒŒ ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ wrapper๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

class SomePlugin extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.somePlugin();
  }

  componentWillUnmount() {
    this.$el.somePlugin('destroy');
  }

  render() {
    return <div ref={(el) => (this.el = el)} />;
  }
}
  • ์ตœ์ƒ์œ„ DOM ์—˜๋ฆฌ๋จผํŠธ์— ref๋ฅผ ๋ถ™์ธ๋‹ค.
  • render() ๋ฉ”์„œ๋“œ์—์„œ ๋นˆ <div />๋ฅผ ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์จ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๋„๋ก ๋ง‰๋Š”๋‹ค.
  • componentDidMount, componentWillUnmount ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜์—ฌ jQuery ํ”Œ๋Ÿฌ๊ทธ์ธ์ด DOM์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ํ•ด์ œํ•˜๋„๋ก ํ•œ๋‹ค. (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋“ฑ๋กํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ํ•„์ˆ˜! - ํ•ด์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ ์—†์œผ๋ฉด ๋งŒ๋“ค์–ด์„œ๋ผ๋„)

๊ตฌ์ฒด์  ์˜ˆ์‹œ - jquery Chosen ํ”Œ๋Ÿฌ๊ทธ์ธ

function Example() {
  return (
    <Chosen onChange={(value) => console.log(value)}>
      <option>vanilla</option>
      <option>chocolate</option>
      <option>strawberry</option>
    </Chosen>
  );
}
class Chosen extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();

    this.handleChange = this.handleChange.bind(this);
    this.$el.on('change', this.handleChange);
  }

  componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger('chosen:updated');
    }
  }

  componentWillUnmount() {
    this.$el.off('change', this.handleChange);
    this.$el.chosen('destroy');
  }

  handleChange(e) {
    this.props.onChange(e.target.value);
  }

  render() {
    return (
      <div>
        <select className="Chosen-select" ref={(el) => (this.el = el)}>
          {this.props.children}
        </select>
      </div>
    );
  }
}
  • React๊ฐ€ ๊ด€์—ฌํ•˜๋Š” ํ•œ <div>๋Š” ํ•ญ์ƒ ๋‹จ์ผ ์ž์‹๋งŒ ๊ฐ€์ง€๋ฉฐ, React ์—…๋ฐ์ดํŠธ๋Š” Chosen์— ์˜ํ•ด ์ถ”๊ฐ€๋œ ์™ธ๋ถ€ DOM ๋…ธ๋“œ์™€ ์ถฉ๋Œํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • componentDidMount์—์„œ <select> ๋…ธ๋“œ์˜ ref๋ฅผ ํ†ตํ•ด Chosen์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , componentWillUnmount์—์„œ ํ•ด์ œํ•œ๋‹ค.
  • ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์•Œ๋ฆผ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด Chosen์ด ๊ด€๋ฆฌํ•˜๋Š” <select>์—์„œ jQuery change ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•œ๋‹ค. this.props.onChange๋ฅผ ํ˜ธ์ถœํ•˜๋Š” handleChange() ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•˜๊ณ  jQuery change ์ด๋ฒคํŠธ๋กœ ๊ตฌ๋…ํ•œ๋‹ค. (DidMount์—์„œ on, WillUnmount์—์„œ off)
  • React๊ฐ€ DOM์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, props๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ์ˆ˜๋™์œผ๋กœ DOM์„ ์—…๋ฐ์ดํŠธํ•ด์ค˜์•ผ ํ•œ๋‹ค. componentDidUpdate์—์„œ props๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๊ฒฝ์šฐ Chosen์—๊ฒŒ trigger() API๋ฅผ ํ†ตํ•ด ์•Œ๋ ค์ค€๋‹ค.

๋‹ค๋ฅธ ๋ทฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ†ตํ•ฉํ•˜๊ธฐ

ReactDOM.render() ๋ฉ”์„œ๋“œ๋Š” ๋…๋ฆฝ์ ์ธ UI์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ์œ ์—ฐ์„ฑ ๋•๋ถ„์— ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— React๋ฅผ ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ ๋ Œ๋”๋ง์„ React๋กœ ๋ฐ”๊พธ๊ธฐ

์ด์ „ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ $el.html(htmlString) ์ฒ˜๋Ÿผ DOM์˜ ์ผ๋ถ€๋ถ„์„ ๋ฌธ์ž์—ด๋กœ์„œ DOM์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค. ์ด๋ฅผ React ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ jQuery ๊ตฌํ˜„์€

$('#container').html('<button id="btn">Say Hello</button>');
$('#btn').click(function () {
  alert('Hello!');
});

๋‹ค์Œ๊ณผ ๊ฐ™์ด React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด ์žฌ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

function Button() {
  return <button id="btn">Say Hello</button>;
}

ReactDOM.render(<Button />, document.getElementById('container'), function () {
  $('#btn').click(function () {
    alert('Hello!');
  });
});

๋‹ค๋งŒ, ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ID๋ฅผ ํ†ตํ•œ ๋ฐฉ์‹์ด ์•„๋‹Œ React ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹๋‹ค.

function Button(props) {
  return <button onClick={props.onClick}>Say Hello</button>;
}

function HelloButton() {
  function handleClick() {
    alert('Hello!');
  }
  return <Button onClick={handleClick} />;
}

ReactDOM.render(<HelloButton />, document.getElementById('container'));

๊ตฌ์ฒด์  ์˜ˆ์‹œ - Backbone ๋ทฐ

Backbone ๋ทฐ๋Š” ๋ฌธ์ž์—ด์„ ํ†ตํ•ด DOM ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ReactDOM.render() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด React ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

function Paragraph(props) {
  return <p>{props.text}</p>;
}

const ParagraphView = Backbone.View.extend({
  render() {
    // Backbone์˜ render() ํ•จ์ˆ˜ ์˜ค๋ฒ„๋ผ์ด๋“œ
    const text = this.model.get('text');
    // `this.el`์ด ์ œ๊ณตํ•˜๋Š” DOM ์š”์†Œ์— <Paragraph /> ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง
    ReactDOM.render(<Paragraph text={text} />, this.el);
    return this;
  },
  remove() {
    // React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ธฐํƒ€ ์ž์›๋“ค์„ ๋“ฑ๋ก ํ•ด์ œ
    ReactDOM.unmountComponentAtNode(this.el);
    Backbone.View.prototype.remove.call(this);
  },
});

์ด ์ด์ƒ์˜ ๋‚ด์šฉ๋“ค์€ ๋‚˜์ค‘์— ์ฐพ์•„๋ณด๋Š” ๊ฒƒ์ด ๋” ์œ ์ตํ•  ๊ฒƒ ๊ฐ™์•„์„œ ์ด ์ •๋„๋กœ๋งŒ ์ •๋ฆฌํ•˜๊ฒ ๋‹ค. ์ด๋ฒˆ ๋ฌธ์„œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ†ตํ•ฉํ•˜๊ธฐ์— ๋Œ€ํ•œ ๋ง›๋ณด๊ธฐ์šฉ !! (Backbone์„ ์จ๋ณธ ๊ฒฝํ—˜์ด ์—†๊ณ  ์ž˜ ๋ชจ๋ฆ„, ๋‚˜์ค‘์— ์“ธ ์ผ์ด ์ƒ๊ธธ ๋•Œ ์ฐพ์•„๋ณด๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์Œ)