[ReactJS로 영화 웹 만들기] 1. state - 단위 변환기 만들기

이민선(Jasmine)·2022년 12월 11일
0
post-thumbnail

60분을 입력하면 1시간을 출력해주고, 2시간을 입력하면 120분을 출력해주는 변환기가 있다면?
그리고 그런 변환기를 직접 만들어볼 수 있다면?
그걸 인적성 응용수리 풀 때 사용할 수 있다면? (그건 안된다 )

노마드코더 리액트JS를 수강하며 직접 만들어보았다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <script type="text/babel">
    function MinutesToHours() {
      const [amount, setAmount] = React.useState("");
      const [flipped, setFlipped] = React.useState(false);
      const onChange = (event) => {
        setAmount(event.target.value);
      };
      const reset = () => setAmount(0);
      const onFlip = () => {
        reset();
        setFlipped((current) => !current);
      };
      return (
        <div>
          <div>
            <label htmlFor='minutes'>Minutes</label>{" "}
            {/* class는 className, for는 htmlFor로 지정*/}
            <input
              value={flipped ? amount * 60 : amount}
              id='minutes'
              placeholder='Minutes'
              type='number'
              onChange={onChange}
              disabled={flipped}
            />
          </div>

          <div>
            <label htmlFor='hours'>Hours</label>
            <input
              value={flipped ? amount : Math.round(amount / 60)}
              id='hours'
              placeholder='Hours'
              type='number'
              onChange={onChange}
              disabled={!flipped}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>{flipped ? "H -> M" : "M -> H"}</button>
        </div>
      );
    }
    function KmToMiles() {
      const [amount, setAmount] = React.useState("");
      const [flipped, setFlipped] = React.useState(false);
      const onChange = (event) => {
        setAmount(event.target.value);
      };
      const reset = () => setAmount(0);
      const onFlip = () => {
        reset();
        setFlipped((current) => !current);
      };
      return (
        <div>
          <div>
            <label htmlFor='kilometers'>Kilometer</label>{" "}
            {/* class는 className, for는 htmlFor로 지정*/}
            <input
              value={flipped ? amount / 0.6214 : amount}
              id='kilometer'
              placeholder='kilometer'
              type='number'
              onChange={onChange}
              disabled={flipped}
            />
          </div>

          <div>
            <label htmlFor='mile'>mile</label>
            <input
              value={flipped ? amount : amount * 0.6214}
              id='mile'
              placeholder='miles'
              type='number'
              onChange={onChange}
              disabled={!flipped}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>{flipped ? "M -> K" : "K -> M"}</button>
        </div>
      );
    }

    function App() {
      const [index, setIndex] = React.useState("xx");
      const onSelect = (event) => {
        setIndex(event.target.value);
      };
      console.log("render w/", index);
      return (
        <div>
          <h1>Super Converter</h1>
          <select value={index} onChange={onSelect}>
            <option value='xx'>Select your units</option>
            <option value='0'>Minutes & Hours</option>
            <option value='1'>Km & Miles</option>
          </select>
          {index === "xx" ? "Please select your units" : null}
          {index === "0" ? <MinutesToHours /> : null}
          {index === "1" ? <KmToMiles /> : null}
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

APP이라는 부모 컴포넌트에 분<->시간 단위변환기와 킬로미터<->마일 단위 변환기라는 2개의 자식 컴포넌트를 렌더링한 것이다.

⭐️

  • React.useState()는 배열을 반환한다. state와 modifier함수 2개의 원소가 있는 배열이다.
  const [amount, setAmount] = React.useState("");

React.useState()의 괄호 안에는 state의 디폴트 값을 지정해줄 수 있다.
내 단위 변환기에서 amount의 디폴트값은 ""이다. flipped의 디폴트값은 false이다.

  • 2번째 인자인 modifier함수를 통해 state을 바꿀 수 있다.
  • 분을 입력하는 input에서 숫자를 변경할 때 변경된 숫자(amount)를 보여주고 싶다면? input에 onChange함수를 걸고 event를 인자로 전달한다. setAmount가 modify해주는 함수이므로 event.target.value를 setAmount의 인자로 설정하면 된다!

  • flipped 상태도 마찬가지. 초기에 flipped되지 않은 상태라면? button에 onFlip함수를 걸어놓고, 현재 state인 false를 true로 변경할 수 있다. false 상태라면 시간input을 disabled로 막아놓아 분 단위만 입력할 수 있도록 하고, true 상태라면 분input을 disabled로 막아놓아 시간만 입력할 수 있도록 했다.

  • 니꼬쌤의 팁!

      setFlipped((current) => !current);

modifier함수의 인자 부분을 함수로 지정해주어야만 혹여나 다른 곳에서 업데이트가 일어나도 이를 반영할 수가 있다.

  • option에서 index0을 가진 버튼을 누르면 분<->시간 변환기가 나오고, index 1을 가진 버튼을 누르면 KM<->mile 변환기가 나오도록 만들고 싶다면?
return (
        <div>
          <h1>Super Converter</h1>
          <select value={index} onChange={onSelect}>
            <option value='xx'>Select your units</option>
            <option value='0'>Minutes & Hours</option>
            <option value='1'>Km & Miles</option>
          </select>
          {index === "xx" ? "Please select your units" : null}
          {index === "0" ? <MinutesToHours /> : null}
          {index === "1" ? <KmToMiles /> : null}
        </div>
      );

아주 멋진 select 태그 ^^
각 옵션의 index를 지정해놓고(0 또는 1), 선택한 값에 따라 렌더링할 컴포넌트를 정하는 것이다.

  • 마지막에
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);

html에 설정해놓은 root 태그에 App을 렌더링하기 위해 마지막 줄을 잊지 말 것! (물론 코드 마지막에 있다고 해서 마무리할 때 써야 하는 코드는 아니다 ㅋㅋㅋ 진작 rendering 해놓으려면 초반에 신경써야 할 관문이라고 할 수 있지 !)

profile
기록에 진심인 개발자 🌿

0개의 댓글