이론 (Front-end)/React

[React] select 태그를 통한 컴포넌트 제어

이우열 2023. 7. 12. 23:33
728x90

✅ Select 태그 값에 따라 변하는 컴포넌트

 

웹을 개발하다보면 select 태그 값에 따라 변하는 내용을 만들어야 할 때가 있습니다.

 

React에서는 변하는 내용을 컴포넌트화하여 select 값에 따라 다른 컴포넌트를 렌더링하는 방식을 사용합니다.

 

 

먼저 가장 Root 컴포넌트인 App에서 select 태그를 만들어봅시다.

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>
      <hr />
      {index === "xx" ? "Please select your units" : null}
      {index === "0" ? <MinutesToHours /> : null}
      {index === "1" ? <KmToMiles /> : null}
    </div>
  );
}

select 태그의 값index라는 state로 연결하고 변화를 감지하여 index 값을 업데이트해줍니다.

 

아무 것도 선택되지 않았을 때의 값을 "xx"라고 하고

분 & 시를 변환해주는 컴포넌트를 띄우기 위한 값은 "0"이며

킬로미터 & 마일을 변환해주는 컴포넌트를 띄우기 위한 값은 "1"이라고 해봅시다.

 

컴포넌트를 불러오기 위해

삼항연산자를 사용하여 index의 값을 비교해줍니다.

각각의 컴포넌트는 해당 값이 아닐 경우에는 보여지면 안되기 때문에 false일 경우는 null이라고 해줍니다.

 

 

✏️ MinutesToHours 컴포넌트

function MinutesToHours() {
  const [amount, setAmount] = React.useState(0);
  const [inverted, setInverted] = React.useState(false);
  const onChange = (event) => {
    setAmount(event.target.value);
  };
  const reset = () => {
    setAmount(0);
  };
  const onInvert = () => {
    reset();
    setInverted((current) => !current);
  };
  return (
    <div>
      <h3>Minutes 2 Hours</h3>
      <div>
        <label htmlFor="minutes">Minutes</label>
        <input
          value={inverted ? amount * 60 : amount}
          id="minutes"
          placeholder="Minutes"
          type="number"
          onChange={onChange}
          disabled={inverted}
        />
      </div>

      <div>
        <label htmlFor="hours">Hours</label>
        <input
          value={inverted ? amount : amount / 60}
          id="hours"
          placeholder="Hours"
          type="number"
          onChange={onChange}
          disabled={!inverted}
        />
      </div>

      <button onClick={reset}>Reset</button>
      <button onClick={onInvert}>
        {inverted ? "Turn back" : "Invert"}
      </button>
    </div>
  );
}

 

 

✏️ KmToMiles 컴포넌트

function KmToMiles() {
  const [amount, setAmount] = React.useState(0);
  const [inverted, setInverted] = React.useState(false);
  function onChange() {
    setAmount(event.target.value);
  }
  function reset() {
    setAmount(0);
  }
  function onInvert() {
    reset();
    setInverted((current) => !current);
  }
  return (
    <div>
      <h3>Kilometers 2 Miles</h3>
      <div>
        <label for="">Kilometers</label>
        <input
          value={inverted ? amount * 1.60934 : amount}
          type="number"
          disabled={inverted}
          onChange={onChange}
        />
      </div>

      <div>
        <label for="">Miles</label>
        <input
          value={inverted ? amount : amount / 1.60934}
          type="number"
          disabled={!inverted}
          onChange={onChange}
        />
      </div>

      <button onClick={reset}>Reset</button>
      <button onClick={onInvert}>
        {inverted ? "Turn back" : "Invert"}
      </button>
    </div>
  );
}
728x90