웹 개발/React

React(리액트) State를 이용해 단위 변환기 구현하기

restudy 2024. 2. 16. 23:37
반응형

이번 시간에는 React(리액트)의 State를 이용해 단위 변환기를 구현해보도록 하겠습니다.

 

리액트에서 State는 이름 그대로 '컴포넌트의 상태', 또는 '컴포넌트 안에서 관리되는 데이터'를 의미합니다.

State를 이용해 어떤 컴포넌트의 상태를 변경하면, React는 자동으로 이 컴포넌트만을 다시 렌더링하여 변경된 상태를 페이지에 반영해줍니다.

 

React의 State를 사용하는 것이 좋은 이유는, 리액트는 앞서 말한대로 필요한 부분만 다시 렌더링하므로, 값이 바뀐다고 페이지 전체를 다시 렌더링할 필요가 없기 때문입니다.

따라서 매우 효율적으로, 화면에 변화가 필요한 부분만을 다시 로딩할 수 있습니다.

 

물론 Vanilla Javascript에서도 수동적으로 DOM을 조작할 수 있지만, 매우 긴 코드가 필요하고 따라서 번거롭습니다.

하지만 리액트의 State를 사용한다면 리액트가 자동으로 변경 사항을 감지하고 UI를 업데이트해 줄 수 있습니다.

 

index.html 실행 결과

 

앞서 언급한대로 이 포스트에서는 위와 같은 '시간 ↔ 분 변환기'를 구현해볼 것입니다.

index.html의 코드는 다음과 같습니다.

 

<!-- index.html -->
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function App() {
      const [amount, setAmount] = React.useState(0);
      const [inverted, setInverted] = React.useState(false);
      const onChange = (event) => {
        setAmount(event.target.value);
      };
      const reset = () => setAmount(0);
      const onFlip = () => {
        reset();
        setInverted((current) => !current);
      };
      return (
        <div>
          <h1>시간 ↔ 분 변환기</h1>
          <div>
            <input
              value={inverted ? Math.round(amount * 60 * 100) / 100 : amount}
              id="minutes"
              placeholder="분"
              type="number"
              onChange={onChange}
              disabled={inverted}
              style={{ textAlign: "right" }}
            />
            <label htmlFor="minutes"> 분</label>
          </div>
          <div>
            <input
              value={inverted ? amount : Math.round((amount / 60) * 100) / 100}
              id="hours"
              placeholder="시간"
              type="number"
              disabled={!inverted}
              onChange={onChange}
              style={{ textAlign: "right" }}
            />
            <label htmlFor="hours"> 시간</label>
          </div>
          <button onClick={reset}>초기화</button>
          <button onClick={onFlip}>뒤집기</button>
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

주목해서 볼만한 부분을 자세히 살펴보겠습니다.

 

const [amount, setAmount] = React.useState(0);
const [inverted, setInverted] = React.useState(false);

 

먼저 여기서는 amountinverted라는 state를 사용합니다.

amount는 input 태그에 입력된 값을 나타내고, inverted는 false면 위 칸이 활성화, true면 아래 칸이 활성화되도록 할 것입니다.

 

useState리액트에 내장되어있는 훅(Hook)의 한 종류입니다. (여기서 훅은 컴포넌트의 상태나 생명주기 등을 관리할 수 있도록 도와주는 기능을 뜻합니다.)

 

useState() 함수는 두 개의 값을 반환하는데, 첫 번째 값은 상태, 두 번째 값은 해당 상태를 업데이트할 수 있는 함수입니다.

따라서 우리는 [value, setValue]와 같이 상태와 업데이트 함수를 각각 받아올 수 있습니다.

useState 함수의 인자로는 상태의 초깃값을 지정해주면 됩니다.

 

<input
  value={inverted ? Math.round(amount * 60 * 100) / 100 : amount}
  id="minutes"
  type="number"
  onChange={onChange}
  disabled={inverted}
/>

 

첫 번째 input 태그만 살펴봅시다.

우선 inverted가 true인 경우 아래 칸의 입력에 따라 현재 칸의 값을 설정할 것입니다.

위 칸은 단위가 시간이고, 아래 칸은 단위가 분이므로, amount(시간)을 (분)으로 변환하기 위해 60을 곱해주면 됩니다.

만약 inverted가 false인 경우는 현재 칸이 활성화된 것이므로 입력한 값 그대로 value로 설정해주면 됩니다.

 

이제 onChange 이벤트를 살펴봅시다.

이 이벤트는 사용자가 입력 필드의 값을 바꿀 때마다 발생합니다.

따라서 이 경우 실행할 함수를 정의해두고 적어주면, 값이 바뀔 때마다 호출이 될 것입니다.

여기서는 onChange() 함수를 사용할 것입니다.

 

그렇다면 onChange() 함수를 살펴볼까요?

 

const onChange = (event) => {
  setAmount(event.target.value);
};

 

onChange() 함수의 구현은 이 포스트에 한해서는 별 내용이 없습니다.

왜냐하면 그냥 변화된 값을 그대로 input 내용으로 반영해주기만 하면 되기 때문입니다.

발생한 이벤트 객체를 event라고 했을 때, event.target.value와 같이 접근하면 입력 필드에 입력된 값에 접근할 수 있습니다.

이 값을 setAmount를 이용해 업데이트해주면, 리액트가 실시간으로 해당 컴포넌트를 업데이트 해줍니다.

 

이렇게 두 번째 input 태그도 비슷한 원리로 작성해주면, 단위 변환기를 성공적으로 구현할 수 있습니다.

 

뒤집기를 눌러 invert 시킨 후 값을 입력한 결과

 

위와 같이 뒤집기 버튼을 누른 후 시간 값을 입력해도 분 단위로 잘 변화가 일어나는 것을 확인할 수 있습니다.

 

 

반응형