[TIL] 220324

Lee SyongΒ·2022λ…„ 3μ›” 24일
0

TIL

λͺ©λ‘ 보기
202/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. react - λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈ(ref 생성 및 μ ‘κ·Ό) vs μ œμ–΄ μ»΄ν¬λ„ŒνŠΈ

πŸ“š 배운 것

μƒˆλ‘­κ²Œ μ•Œκ²Œ 된 λ‚΄μš©μ΄κ±°λ‚˜ μ΄ν•΄ν•˜κΈ° μ–΄λ €μ› λ˜ λΆ€λΆ„λ§Œ 정리

1. λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈ

React: μ œμ–΄ μ»΄ν¬λ„ŒνŠΈμ™€ λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈμ˜ 차이점 μ°Έκ³ 

μ œμ–΄ μ»΄ν¬λ„ŒνŠΈμ—μ„œ 폼 λ°μ΄ν„°λŠ” React μ»΄ν¬λ„ŒνŠΈμ—μ„œ 닀루어지고, μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€ λ‘œμ§μ— μ˜ν•΄μ„œ 화면에 λ³΄μ—¬μ§€λŠ” 값이 λ³€ν•œλ‹€.

λ°˜λ©΄μ—, λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” 폼 λ°μ΄ν„°λŠ” DOM μžμ²΄μ—μ„œ 닀루어지고, μ‚¬μš©μžμ— μ˜ν•΄ 화면에 λ³΄μ—¬μ§€λŠ” 값이 λ³€ν•œλ‹€.

1) Ref와 DOM

(1) refλž€?

refλŠ” render λ©”μ„œλ“œμ—μ„œ μƒμ„±λœ 'DOM λ…Έλ“œ'λ‚˜ 'React μ—˜λ¦¬λ¨ΌνŠΈ'에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.
일반적으둜 React의 데이터 ν”Œλ‘œμš°μ—μ„œ λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ μžμ‹ μ»΄ν¬λ„ŒνŠΈλ₯Ό μˆ˜μ •ν•˜λ €λ©΄ μƒˆλ‘œμš΄ propsλ₯Ό μ „λ‹¬ν•˜μ—¬ μžμ‹ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‹€μ‹œ λ Œλ”λ§ν•΄μ•Ό ν•œλ‹€.
κ·ΈλŸ¬λ‚˜, refλ₯Ό μ‚¬μš©ν•˜λ©΄ λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ μžμ‹ μ»΄ν¬λ„ŒνŠΈλ₯Ό 직접 μˆ˜μ •ν•  수 μžˆλ‹€.

refλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  해결될 수 μžˆλ‹€λ©΄ refλ₯Ό μ‚¬μš©ν•˜λŠ” 것은 μ§€μ–‘λœλ‹€.
refλŠ” λ‹€μŒκ³Ό 같은 μƒν™©μ—μ„œ μ‚¬μš©λ  수 μžˆλ‹€.

  • 포컀슀, ν…μŠ€νŠΈ μ„ νƒμ˜μ—­, ν˜Ήμ€ λ―Έλ””μ–΄μ˜ μž¬μƒμ„ 관리할 λ•Œ
  • μ• λ‹ˆλ©”μ΄μ…˜μ„ μ§μ ‘μ μœΌλ‘œ μ‹€ν–‰μ‹œν‚¬ λ•Œ
  • μ„œλ“œ νŒŒν‹° DOM 라이브러리λ₯Ό React와 같이 μ‚¬μš©ν•  λ•Œ

(2) ref 생성 및 μ ‘κ·Ό

  • DOM μ—˜λ¦¬λ¨ΌνŠΈμ— Ref μ‚¬μš©ν•˜κΈ°

    button input을 ν΄λ¦­ν•˜λ©΄ text input이 focus λ˜λ„λ‘ ν•˜λ €κ³  ν•œλ‹€.
    render λ©”μ„œλ“œμ—μ„œ μƒμ„±λœ DOM μ—˜λ¦¬λ¨ΌνŠΈμ— μ ‘κ·Όν•˜λ €λŠ” 것이닀.

    λ‹€μŒκ³Ό 같이 ref μ–΄νŠΈλ¦¬λ·°νŠΈκ°€ HTML μ—˜λ¦¬λ¨ΌνŠΈμ— 쓰인 경우, μƒμ„±μžμ—μ„œ React.createRef()둜 μƒμ„±λœ refλŠ”, μžμ‹ μ„ 전달받은 DOM μ—˜λ¦¬λ¨ΌνŠΈ(λ‹€μŒ 예제의 경우, input type="text")λ₯Ό current ν”„λ‘œνΌν‹°μ˜ κ°’μœΌλ‘œ λ°›λŠ”λ‹€.

class CumstomTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef(); // μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€κ°€ 생성될 λ•Œ refλ₯Ό κ·Έ ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€
    this.focusTextInput = this.focusTextInput.bind(this);
  }
  
  focusTextInput() {
    this.textInput.current.focus();
    
    // console.log(this.textInput.current); // input
  }
  
  render() {
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} // μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€μ˜ μ–΄λŠ κ³³μ—μ„œλ„ ref에 μ ‘κ·Ό κ°€λŠ₯
        />
        <input
          type="button"
          value="focus"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
  • 클래슀 μ»΄ν¬λ„ŒνŠΈμ— ref μ‚¬μš©ν•˜κΈ°

    ν•œνŽΈ, μ—¬κΈ°μ„œ 더 λ‚˜μ•„κ°€ button input을 직접 ν΄λ¦­ν•˜κΈ°λ„ 전에 μ»΄ν¬λ„ŒνŠΈκ°€ 마운트된 직후 text input이 μ¦‰μ‹œ 포컀슀 받도둝 ν•˜λ €κ³  ν•œλ‹€.
    render λ©”μ„œλ“œμ—μ„œ React μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€μ— μ ‘κ·Όν•˜λ €λŠ” 것이닀.

    λ‹€μŒκ³Ό 같이 ref μ–΄νŠΈλ¦¬λ·°νŠΈκ°€ μ»€μŠ€ν…€ 클래슀 μ»΄ν¬λ„ŒνŠΈμ— 쓰인 경우, μƒμ„±μžμ—μ„œ React.createRef()둜 μƒμ„±λœ refλŠ”, 마운트된 μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€(λ‹€μŒ 예제의 경우, CustomTextInput)λ₯Ό current ν”„λ‘œνΌν‹°μ˜ κ°’μœΌλ‘œ λ°›λŠ”λ‹€.

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }
  
  componentDidMount() {
    this.textInput.current.focusTextInput();
    
    // console.log(this.textInput.current); // CustomTextInput
  }
  
  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

ReactDOM.render(
  <AutoFocusTextInput />,
  document.getElementById("root")
);
  • ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈμ—/μ—μ„œ ref μ‚¬μš©ν•˜κΈ°

    (1) λ°˜λ©΄μ—, ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈλŠ” μΈμŠ€ν„΄μŠ€κ°€ μ—†κΈ° λ•Œλ¬Έμ— ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'μ—λŠ”' ref μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.

    (2) κ·ΈλŸ¬λ‚˜, ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'μ—μ„œ' (render λ©”μ„œλ“œμ—μ„œ μƒμ„±λœ DOM μ—˜λ¦¬λ¨ΌνŠΈμ— μ ‘κ·Όν•˜κΈ° μœ„ν•΄) ref μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” 것은 κ°€λŠ₯ν•˜λ‹€.

    cf. μ΄λ•Œ ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” createRef λŒ€μ‹  useRefλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
    ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈμ—μ„œ createRefλ₯Ό μ‚¬μš©ν•˜λ©΄ setStateκ°€ 호좜되고 μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ createRef도 λ‹€μ‹œ ν˜ΈμΆœλ˜μ–΄ ref.currentκ°€ null둜 μ΄ˆκΈ°ν™”λ˜κΈ° λ•Œλ¬Έμ΄λ‹€.
    λ”°λΌμ„œ, ref.current의 값을 μœ μ§€ν•˜κΈ° μœ„ν•΄ useRefλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

// (1)의 경우
function MyFunctionComponent() {
  return <input />;
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }
  render() {
    // ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'μ—λŠ”' ref μ–΄νŠΈλ¦¬λ·°νŠΈ μ‚¬μš© λΆˆκ°€λŠ₯
    return (
      <MyFunctionComponent ref={this.textInput} />
    );
  }
}
// (2)의 경우
function CustomTextInput(props) {
  // textInput은 ref μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό 톡해 μ „λ‹¬λ˜κΈ° μœ„ν•΄μ„œ μ΄κ³³μ—μ„œ μ •μ˜λ˜μ–΄μ•Ό 함
  const textInput = useRef(null);

  function handleClick() {
    textInput.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} /> {/* ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'μ—μ„œ' ref μ–΄νŠΈλ¦¬λ·°νŠΈ μ‚¬μš© κ°€λŠ₯ */}
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}

λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ, 'μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ DOM μ—˜λ¦¬λ¨ΌνŠΈ'에 μ ‘κ·Όν•˜κ³ μž ν•  λ•Œ refλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
(μœ„ μ˜ˆμ œλ“€μ€ '직접 λ Œλ”λ§ν•˜λŠ” DOM μ—˜λ¦¬λ¨ΌνŠΈ' ν˜Ήμ€ λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ 'μžμ‹ μ»΄ν¬λ„ŒνŠΈ'에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ refλ₯Ό μ‚¬μš©ν•œ κ²½μš°μ˜€λ‹€.)

'μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ DOM μ—˜λ¦¬λ¨ΌνŠΈ'에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄μ„œλ„ μœ„μ™€ 같이 μžμ‹ μ»΄ν¬λ„ŒνŠΈμ— ref μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μ§€μ •ν•˜λŠ” 방식을 μ‚¬μš©ν•  수 있긴 ν•˜μ§€λ§Œ
μ΄λŠ” μœ„μ—μ„œ μ‚΄νŽ΄λ΄€λ“― μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€μ˜ DOM μ—˜λ¦¬λ¨ΌνŠΈκ°€ μ•„λ‹ˆλΌ μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ Έμ˜¨λ‹€λŠ” μ μ—μ„œ, 그리고 μžμ‹ μ»΄ν¬λ„ŒνŠΈκ°€ ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈμΈ κ²½μš°μ—λŠ” μžμ‹ μ»΄ν¬λ„ŒνŠΈμ— μ‚¬μš©ν•  수 μ—†λŠ”λ‹€λŠ” μ μ—μ„œ, 쒋은 방법이 μ•„λ‹ˆλ‹€.

λŒ€μ‹ μ— (React 16.3 이후 λ²„μ „μ˜ Reactλ₯Ό μ‚¬μš© 쀑이라면) λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ 'μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ DOM μ—˜λ¦¬λ¨ΌνŠΈ'에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ refλ₯Ό μ „λ‹¬ν•˜λŠ” 방법을 μ‚¬μš©ν•  수 μžˆλ‹€.
μ΄λŠ” λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈκ°€ μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ refλ₯Ό μžμ‹ μ˜ refλ‘œμ„œ 외뢀에 λ…ΈμΆœμ‹œν‚€λŠ” 방법을 λ§ν•œλ‹€.

React.forwardRef()λ₯Ό μ΄μš©ν•΄ 일뢀 μ»΄ν¬λ„ŒνŠΈ(λ‹€μŒ 예제의 경우, < FancyButton />)κ°€ μˆ˜μ‹ ν•œ refλ₯Ό λ°›μ•„ 쑰금 더 μ•„λž˜λ‘œ 전달(즉, '전솑')ν•  수 μžˆλŠ” 옡트인 κΈ°λŠ₯이닀. (옡트인: λ‹Ήμ‚¬μžκ°€ 개인 데이터 μˆ˜μ§‘μ„ ν—ˆμš©ν•˜κΈ° μ „κΉŒμ§€ λ‹Ήμ‚¬μžμ˜ 데이터 μˆ˜μ§‘μ„ κΈˆμ§€ν•˜λŠ” μ œλ„)
ref μ–΄νŠΈλ¦¬λ·°νŠΈκ°€ HTML μ—˜λ¦¬λ¨ΌνŠΈμ— 쓰인 경우, ref κ°μ²΄λŠ” μžμ‹ μ„ 전달받은 DOM μ—˜λ¦¬λ¨ΌνŠΈλ₯Ό, κ·Έ current ν”„λ‘œνΌν‹°μ˜ κ°’μœΌλ‘œ λ°›λŠ” 것을 μ΄μš©ν•œ 방법이닀.

// 3. 이 refλ₯Ό forwardRef λ‚΄λΆ€μ˜ (props, ref) => ... ν•¨μˆ˜μ˜ 두 번째 인자둜 전달
const FancyButton = React.forwardRef((props, ref) => {
  return (
    <button ref={ref} className="FancyButton"> {/* 4. 이 refλ₯Ό <button>으둜 전달 */}
      {props.children}
    </button>
  );
});

const App = () => {
  const ref = React.createRef(); // 1. createRefλ₯Ό ν˜ΈμΆœν•˜μ—¬ refλ₯Ό μƒμ„±ν•˜κ³  ref λ³€μˆ˜μ— ν• λ‹Ή
  
  const onMouseOver = () => {
    ref.current.focus();
    
    // 5. 졜초 μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§μ΄ λλ‚˜λ©΄, ref.currentλŠ” <button> DOM λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€κ²Œ 됨
    // console.log(ref.current); // <button class="FancyButton">Click me!</button>
  };
  
  return (
    <div>
      <input onMouseOver={onMouseOver}/>
      <FancyButton ref={ref}>Click me!</FancyButton> {/* 2. refλ₯Ό <FancyButton />으둜 전달 */}
    </div>
  );
};

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

(3) 콜백 ref

refλ₯Ό μ„€μ •ν•˜κΈ° μœ„ν•œ 또 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ refκ°€ μ„€μ •λ˜κ³  ν•΄μ œλ˜λŠ” 상황을 μ„Έμ„Έν•˜κ²Œ λ‹€λ£° 수 μžˆλŠ” 콜백 refκ°€ μžˆλ‹€.

μœ„μ—μ„œ μ‚΄νŽ΄λ΄€λ˜ κ²ƒκ³ΌλŠ” 달리 ref μ–΄νŠΈλ¦¬λ·°νŠΈμ— React.createRef()λ₯Ό 톡해 μƒμ„±λœ ref 객체λ₯Ό μ „λ‹¬ν•˜λŠ” λŒ€μ‹ μ—, ref 콜백 ν•¨μˆ˜λ₯Ό μ „λ‹¬ν•œλ‹€.

ref μ½œλ°±μ€ 인라인 ν•¨μˆ˜λ‘œ μ„ μ–Έν•˜κΈ°λ³΄λ‹€ ν΄λž˜μŠ€μ— λ°”μΈλ”©λœ λ©”μ„œλ“œλ‘œ μ„ μ–Έν•˜λŠ” 것이 μ’‹λ‹€.

ν•œνŽΈ, refλ₯Ό μˆ˜μ •ν•˜λŠ” μž‘μ—…κ³Ό ref 콜백 λͺ¨λ‘ componentDidMount λ˜λŠ” componentDidUpdateκ°€ 호좜되기 전에 μˆ˜ν–‰λ˜κ³  ν˜ΈμΆœλœλ‹€.

  • DOM μ—˜λ¦¬λ¨ΌνŠΈμ— 콜백 ref μ „λ‹¬ν•˜κΈ°
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);

    this.textInput = null; // 1. DOM μ—˜λ¦¬λ¨ΌνŠΈ(λ˜λŠ” μžμ‹ μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€)에 λŒ€ν•œ μ°Έμ‘°λ₯Ό μ €μž₯ν• , λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹° λ§Œλ“€κΈ°

    this.setTextInputRef = element => {
      this.textInput = element; // 4. 이λ₯Ό λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°μ— μ €μž₯함
      
      // 3.  ref μ½œλ°±μ€ ref μ–΄νŠΈλ¦¬λ·°νŠΈκ°€ 쓰인 DOM μ—˜λ¦¬λ¨ΌνŠΈ(λ˜λŠ” μžμ‹ μ»΄ν¬λ„ŒνŠΈμ˜ μΈμŠ€ν„΄μŠ€)λ₯Ό 인자둜 λ°›μŒ
      // console.log(element); // <input type="text">
    };

    // ( constructor μ•ˆμ— μ •μ˜λ˜μ–΄ μžˆμœΌλ―€λ‘œ λ°‘μ—μ„œ 이벀트 ν•Έλ“€λŸ¬ ν•¨μˆ˜λ‘œ μ‚¬μš©λ  λ•Œ this 바인딩 μ•ˆν•΄λ„ λœλ‹€ )
    this.focusTextInput = () => {
      // 6. 졜초 μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§ μ‹œ μžλ™μœΌλ‘œ 포컀슀 됨, κ·Έ ν›„ λ²„νŠΌ λˆ„λ₯Ό λ•Œλ§ˆλ‹€ 포컀슀됨
      // => render λ©”μ„œλ“œμ— μ˜ν•΄ μƒμ„±λ˜λŠ” DOM μ—˜λ¦¬λ¨ΌνŠΈμ— μ ‘κ·Όν•  수 있게 λ˜μ—ˆλ‹€!
      if (this.textInput) {
        this.textInput.focus();
      }
    };
  } // ( ...μ—¬κΈ°κΉŒμ§€κ°€ constructor )

  componentDidMount() { // 5. 졜초 μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§μ΄ λλ‚œ ν›„ componentDidMount λ©”μ„œλ“œκ°€ 호좜됨
    this.focusTextInput();
  }

  render() {
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef} {/* 2. render λ©”μ„œλ“œκ°€ 호좜되면 componentDidMount 호좜 전에 ref 콜백이 호좜됨 */}
        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

ReactDOM.render(
  <CustomTextInput/>,
  document.getElementById("root")
);
  • μžμ‹ μ»΄ν¬λ„ŒνŠΈμ— 콜백 ref μ „λ‹¬ν•˜κΈ°
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} /> {/* ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'에선' refλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. */}
    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    
    this.inputElement = null;
  }
  
  inputRef(element) {
    this.inputElement = element;
  }
  
  componentDidMount() {
    this.inputElement.focus();
  }
  
  render() {
    return (
      <CustomTextInput inputRef={el => this.inputElement = el} />
      {/* props ν”„λ‘œνΌν‹°λ‘œ inputRef(ref 콜백)λ₯Ό μ „λ‹¬ν–ˆλ‹€.
      β€» 주의! ν•¨μˆ˜ μ»΄ν¬λ„ŒνŠΈ'μ—λŠ”' refλŠ” μ‚¬μš©ν•  수 μ—†λ‹€.
      μ—¬κΈ°μ„œλŠ” refλ₯Ό μ‚¬μš©ν•œ 게 μ•„λ‹ˆλΌ inputRefλΌλŠ” prop을 μž‘μ„±ν•œ 것이닀.  */}
    );
  }
}

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

2) defaultValue

React λ Œλ”λ§ 생λͺ… μ£ΌκΈ°μ—μ„œ 폼 μ—˜λ¦¬λ¨ΌνŠΈμ˜ value μ–΄νŠΈλ¦¬λ·°νŠΈλŠ” DOM의 valueλ₯Ό λŒ€μ²΄ν•œλ‹€.
λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•  λ•Œ μ΄ˆκΉƒκ°’μ„ 지정해쀄 순 μžˆμ§€λ§Œ, κ·Έ μ΄ν›„μ˜ μ—…λ°μ΄νŠΈλŠ” μ œμ–΄ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.
이λ₯Ό μœ„ν•΄ JSXμ—μ„œμ˜ value μ–΄νŠΈλ¦¬λ·°νŠΈ λŒ€μ‹  defaultValue μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
μ»΄ν¬λ„ŒνŠΈκ°€ 마운트 된 후에 defaultValue μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό 변경해도 DOM의 값은 μ—…λ°μ΄νŠΈ λ˜μ§€ μ•ŠλŠ”λ‹€.

< input type="checkbox" >와 < input type="radio" >λŠ” defaultCheckedλ₯Ό μ§€μ›ν•˜κ³ , < input >κ³Ό < select >, < textarea >λŠ” defaultValueλ₯Ό μ§€μ›ν•œλ‹€.

class CustomForm extends React.Component {
  constructor(props) {
    super(props);
    
    this.input = React.createRef();
 
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  
  handleSubmit(event) {
    event.preventDefault();
    console.log(this.input.current.value);
  }
  
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input
            defaultValue="Bob"
            type="text"
            ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

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

3) 파일 μž…λ ₯ νƒœκ·Έ

Reactμ—μ„œ <input type="file" />은 ν”„λ‘œκ·Έλž˜λ°μ μœΌλ‘œ 값을 μ„€μ • ν•  수 μ—†κ³  μ‚¬μš©μžλ§Œμ΄ 값을 μ„€μ •ν•  수 있기 λ•Œλ¬Έμ— 항상 λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€.

λ‹€μŒ μ˜ˆμ œμ—μ„œλŠ” onSubmit 이벀트 ν•Έλ“€λŸ¬ ν•¨μˆ˜μ—μ„œ νŒŒμΌμ— μ ‘κ·Όν•˜κΈ° μœ„ν•΄μ„œ DOM μ—˜λ¦¬λ¨ΌνŠΈμ— refλ₯Ό λ§Œλ“€μ—ˆλ‹€.

const CustomForm = () => {
  const fileInput = React.useRef(null);
  
  const onSubmit = (event) => {
    event.preventDefault();
    console.log(fileInput.current.files[0].name);
  };
  
  return (
    <div>
      <form onSubmit={onSubmit}>
        <label htmlFor="file">
          파일: 
          <input id="file" type="file" ref={fileInput} />
        </label>
        <input type="submit" value="submit" />
      </form>
    </div>
  );
};

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

✨ 내일 ν•  것

  1. react effects
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€