We want to hear from you!Take our 2021 Community Survey!
Support Ukraine ๐Ÿ‡บ๐Ÿ‡ฆ Help Provide Humanitarian Aid to Ukraine.

ํผ

HTML ํผ ์—˜๋ฆฌ๋จผํŠธ๋Š” ํผ ์—˜๋ฆฌ๋จผํŠธ ์ž์ฒด๊ฐ€ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์—, React์˜ ๋‹ค๋ฅธ DOM ์—˜๋ฆฌ๋จผํŠธ์™€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ˆœ์ˆ˜ํ•œ HTML์—์„œ ์ด ํผ์€ name์„ ์ž…๋ ฅ๋ฐ›์Šต๋‹ˆ๋‹ค.

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

์ด ํผ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํผ์„ ์ œ์ถœํ•˜๋ฉด ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๊ธฐ๋ณธ HTML ํผ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. React์—์„œ ๋™์ผํ•œ ๋™์ž‘์„ ์›ํ•œ๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, JavaScript ํ•จ์ˆ˜๋กœ ํผ์˜ ์ œ์ถœ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ํผ์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•œ ํ‘œ์ค€ ๋ฐฉ์‹์€ โ€œ์ œ์–ด ์ปดํฌ๋„ŒํŠธ (controlled components)โ€œ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๊ธฐ์ˆ ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ œ์–ด ์ปดํฌ๋„ŒํŠธ (Controlled Component)

HTML์—์„œ <input>, <textarea>, <select>์™€ ๊ฐ™์€ ํผ ์—˜๋ฆฌ๋จผํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž์‹ ์˜ state๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. React์—์„œ๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” state๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์˜ state ์†์„ฑ์— ์œ ์ง€๋˜๋ฉฐ setState()์— ์˜ํ•ด ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” React state๋ฅผ โ€œ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜ (single source of truth)โ€œ๋กœ ๋งŒ๋“ค์–ด ๋‘ ์š”์†Œ๋ฅผ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํผ์„ ๋ Œ๋”๋งํ•˜๋Š” React ์ปดํฌ๋„ŒํŠธ๋Š” ํผ์— ๋ฐœ์ƒํ•˜๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ React์— ์˜ํ•ด ๊ฐ’์ด ์ œ์–ด๋˜๋Š” ์ž…๋ ฅ ํผ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ โ€œ์ œ์–ด ์ปดํฌ๋„ŒํŠธ (controlled component)โ€œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ด์ „ ์˜ˆ์‹œ๊ฐ€ ์ „์†ก๋  ๋•Œ ์ด๋ฆ„์„ ๊ธฐ๋กํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด ํผ์„ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ (controlled component)๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen์—์„œ ์‹คํ–‰ํ•˜๊ธฐ

value ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋Š” ํผ ์—˜๋ฆฌ๋จผํŠธ์— ์„ค์ •๋˜๋ฏ€๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฐ’์€ ํ•ญ์ƒ this.state.value๊ฐ€ ๋˜๊ณ  React state๋Š” ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ ์ถœ์ฒ˜ (single source of truth)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. React state๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ํ‚ค ์ž…๋ ฅ์—์„œ handleChange๊ฐ€ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•  ๋•Œ ๋ณด์—ฌ์ง€๋Š” ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋กœ ์‚ฌ์šฉํ•˜๋ฉด, input์˜ ๊ฐ’์€ ํ•ญ์ƒ React state์— ์˜ํ•ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๋” ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด์ง€๋งŒ, ๋‹ค๋ฅธ UI ์—˜๋ฆฌ๋จผํŠธ์— input์˜ ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ๊ฐ’์„ ์žฌ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

textarea ํƒœ๊ทธ

HTML์—์„œ <textarea> ์—˜๋ฆฌ๋จผํŠธ๋Š” ํ…์ŠคํŠธ๋ฅผ ์ž์‹์œผ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

<textarea>
  Hello there, this is some text in a text area
</textarea>

React์—์„œ <textarea>๋Š” value ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒํ•˜๋ฉด <textarea>๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํผ์€ ํ•œ ์ค„ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜๋Š” ํผ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      value: 'Please write an essay about your favorite DOM element.'    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Essay:
          <textarea value={this.state.value} onChange={this.handleChange} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

this.state.value๋ฅผ ์ƒ์„ฑ์ž์—์„œ ์ดˆ๊ธฐํ™”ํ•˜๋ฏ€๋กœ textarea๋Š” ์ผ๋ถ€ ํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง„์ฑ„ ์‹œ์ž‘๋˜๋Š” ์ ์„ ์ฃผ์˜ํ•ด์ฃผ์„ธ์š”.

select ํƒœ๊ทธ

HTML์—์„œ <select>๋Š” ๋“œ๋กญ ๋‹ค์šด ๋ชฉ๋ก์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด HTML์€ ๊ณผ์ผ ๋“œ๋กญ ๋‹ค์šด ๋ชฉ๋ก์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

<select>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
  <option selected value="coconut">Coconut</option>
  <option value="mango">Mango</option>
</select>

selected ์˜ต์…˜์ด ์žˆ์œผ๋ฏ€๋กœ Coconut ์˜ต์…˜์ด ์ดˆ๊ธฐ๊ฐ’์ด ๋˜๋Š” ์ ์„ ์ฃผ์˜ํ•ด์ฃผ์„ธ์š”. React์—์„œ๋Š” selected ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ตœ์ƒ๋‹จ selectํƒœ๊ทธ์— value ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•œ ๊ณณ์—์„œ ์—…๋ฐ์ดํŠธ๋งŒ ํ•˜๋ฉด๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋” ํŽธํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite flavor:
          <select value={this.state.value} onChange={this.handleChange}>            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen์—์„œ ์‹คํ–‰ํ•˜๊ธฐ

์ „๋ฐ˜์ ์œผ๋กœ <input type="text">, <textarea> ๋ฐ <select> ๋ชจ๋‘ ๋งค์šฐ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋‘ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ value ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜

select ํƒœ๊ทธ์— multiple ์˜ต์…˜์„ ํ—ˆ์šฉํ•œ๋‹ค๋ฉด value ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<select multiple={true} value={['B', 'C']}>

file input ํƒœ๊ทธ

HTML์—์„œ <input type="file">๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ•˜๋‚˜ ์ด์ƒ์˜ ํŒŒ์ผ์„ ์ž์‹ ์˜ ์žฅ์น˜ ์ €์žฅ์†Œ์—์„œ ์„œ๋ฒ„๋กœ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜ File API๋ฅผ ํ†ตํ•ด JavaScript๋กœ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<input type="file" />

๊ฐ’์ด ์ฝ๊ธฐ ์ „์šฉ์ด๊ธฐ ๋•Œ๋ฌธ์— React์—์„œ๋Š” ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋’ท๋ถ€๋ถ„์—์„œ ๋‹ค๋ฅธ ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์ค‘ ์ž…๋ ฅ ์ œ์–ดํ•˜๊ธฐ

์—ฌ๋Ÿฌ input ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ œ์–ดํ•ด์•ผํ•  ๋•Œ, ๊ฐ ์—˜๋ฆฌ๋จผํŠธ์— name ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  event.target.name ๊ฐ’์„ ํ†ตํ•ด ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์–ด๋–ค ์ž‘์—…์„ ํ•  ์ง€ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

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

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

CodePen์—์„œ ์‹คํ–‰ํ•˜๊ธฐ

์ฃผ์–ด์ง„ input ํƒœ๊ทธ์˜ name์— ์ผ์น˜ํ•˜๋Š” state๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ES6์˜ computed property name ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

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

ES5 ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

var partialState = {};
partialState[name] = value;this.setState(partialState);

๋˜ํ•œ, setState()๋Š” ์ž๋™์ ์œผ๋กœ ํ˜„์žฌ state์— ์ผ๋ถ€ state๋ฅผ ๋ณ‘ํ•ฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ œ์–ด๋˜๋Š” Input Null ๊ฐ’

์ œ์–ด ์ปดํฌ๋„ŒํŠธ์— value prop์„ ์ง€์ •ํ•˜๋ฉด ์˜๋„ํ•˜์ง€ ์•Š๋Š” ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. value๋ฅผ ์„ค์ •ํ–ˆ๋Š”๋ฐ ์—ฌ์ „ํžˆ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์‹ค์ˆ˜๋กœ value๋ฅผ undefined๋‚˜ null๋กœ ์„ค์ •ํ–ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์ด๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. (์ฒซ ๋ฒˆ์งธ ์ž…๋ ฅ์€ ์ž ๊ฒจ์žˆ์ง€๋งŒ ์ž ์‹œ ํ›„ ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.)

ReactDOM.render(<input value="hi" />, mountNode);

setTimeout(function() {
  ReactDOM.render(<input value={null} />, mountNode);
}, 1000);

์ œ์–ด ์ปดํฌ๋„ŒํŠธ์˜ ๋Œ€์•ˆ

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

์™„์ „ํ•œ ํ•ด๊ฒฐ์ฑ…

์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ๋ฐฉ๋ฌธํ•œ ํ•„๋“œ ์ถ”์  ๋ฐ ํผ ์ œ์ถœ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์€ ์™„๋ฒฝํ•œ ํ•ด๊ฒฐ์„ ์›ํ•œ๋‹ค๋ฉด Formik์ด ๋Œ€์ค‘์ ์ธ ์„ ํƒ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Formik์€ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ ๋ฐ state ๊ด€๋ฆฌ์— ๊ธฐ์ดˆํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์šฐ๋Š” ๊ฑธ ์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

Is this page useful?Edit this page