C-log

⚛️React Training : Controlled Component&Uncontrolled Component 본문

⚛️React/⚡ver.2

⚛️React Training : Controlled Component&Uncontrolled Component

4:Bee 2024. 2. 2. 17:39
728x90

 이전 시간에 우리는 useState가 동작되는 원리와 useState를 통해서 React DOM이 어떻게 동작하는지 알 수 있었다. 잠시 복기를 해본 다면 UI에서 변동 상항이 있으면 ReactDOM의 render를 통해서 변화된 UI를 변동 시켜야한다. 하지만 useState를 사용하지 않고 ReactDOM에 있는 render함수를 사용해서 변화가 필요한 함수나 부분에 매번 re-render를 하기엔 너무 불편하고 효율적이 못하다 그래서 상태가 변화 되었다는 것을 감지하고 이를 ReactDOM에 인지를 시켜주는 useState Hook을 사용해서 특정 상태가 변화 되었을 때 해당 컴포넌트가 re-render가 될 수 있는 것이다. 다시 말하지만 useState는 상태를 관리하는 Hook일 뿐 render를 직접적으로하는 것과는 거리가 있다.

 이번 포스팅에서는 제어 컴포넌트와 비제어 컴포넌트에 관해서 다룰 것이다. 먼저 제어 컴포넌트는 React의 상태(state)에 의해 제어되는 폼 요소를 나타낸다. React의 state를 사용하여 폼 요소의 현재 상태를 추적하고, 이에 대한 변경은 반드시 React의 state를 업데이트하는 핸들러 함수를 통해 이루어진다. 일반적으로는 useState 또는 클래스형 컴포넌트의 state를 사용한다. 그리고 비제어 컴포넌트는 React의 상태(state)에 의존하지 않고, 직접적으로 DOM 요소에 의해 관리되는 폼 요소를 나타낸다. 일반적으로 React의 Ref를 사용하여 DOM 요소에 접근하고 직접 조작한다. 이 개념을 생각하면서 아래 코드를 살펴보자. 먼저 우리가 태그의 class와 label태그의 for을 사용하려하는데 이는 js의 문법이고 jsx의 문법을 사용해야 하기에 기존 CDN을 조금 변경 할 것이다 변경된 CDN은 아래와 같다.

 
<script src="https://www.unpkg.com/react@17/umd/react.development.js"></script>
<!-- production.min.js -->
<script src="https://www.unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<!-- production.min.js -->
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
 

이로서 우리는 jsx의 문법을 따라야하는데 그건 아래 코드를 설명하면서 다루겠다. 이번 코드는 우리가 분을 시간으로 계산해주는 간다한 코드를 작성하려한다. 

<script type="text/babel">

  function App() {
    const [minutes, setMinutes] = React.useState(0);
    const onChange = (event) => {
      setMinutes(event.target.value);
    };
    const reset = () => {
      setMinutes(0);
    }
 
    return (
      <div>
        <div>
          <h1 className="hi">Super Converter</h1>
          <label htmlFor="minutes">Minutes</label>
          <input
            value={minutes}
            id="minutes"
            placeholder="Minutes"
            type="number"
            onChange={onChange}
          />
        </div>
        <div>
          <label htmlFor="hours">Hours</label>
          <input
            value={Math.round(minutes / 60)}
            id="hours"
            placeholder="Hours"
            type="number"
            disabled
          ></input>
        </div>
        <button onClick={reset}>Reset</button>
      </div>
    )

  }
  const root = document.getElementById("root");
  ReactDOM.render(<App />, root);
</script>

input태그를 사용해서 해당 태그의 text를 삽입하려면 보통 label태그를 이용한다. 해당 label태그 text를 클릭하면 input을 할 수 있게 도와주는데 이를 동작시키려면 input id프로퍼티와 label의 for의 이름이 동일 해야한다. 하지만 이는 js기준에서지만 jsx에선 for가 아닌 htmlfor을 사용해아한다. 그리고 h1태그의 class를 설정하려면 jsx문법에 맞게 className을 사용하면 된다. 현재 코드를 살펴보면 첫 번째 input은 제어 컴포넌트이다. 그 이유는 onChange가 useState와 연결이 되어 있다. 즉, 제어를 할 수 있는 것이다. 하지만 이와 반대로 두 번째 input태그는 비제어 컴포넌트이다. 현재는 프로퍼티로 disable이 되어 있지만 이를 제거하고 브라우저에서 두 번째 input에 값을 기입하려 해도 기입이 되지 않을 것이다. 그렇다 비제어 상태이기 때문이다. 해당 값은 브라우저에서 즉각 확인되지 않고 useRef Hook을 사용해서 값의 결과를 확인하거나 도출 할 수 있다. 이렇게 제어, 비제어 컴포넌트를 알아봤다. 

728x90
Comments