[3] STATE

양서연·2023년 9월 17일

understanding State

state는 기본적으로 데이터가 저장되는 곳이다.
어떻게 하면 React.js 어플에 값이 바뀔 데이터를 담을 수 있을지 배운다.
먼저 최고가 아닌 방식으로 진행하면서 어떤걸 해야하는지 알고 그 다음에 쉬운 방법으로 한다.

React.js는 이전에 렌더링 된 컴포넌트가 어떤 것인지 확인하고 있다. 그리고 다음에 렌더링될 컴포넌트가 어떤지 보고 다른 부분만 파악한다. 우리가 바군 부분만 수정해서 보여주는 것이다.
React.js는 여러가지 요소들을 다시 렌더링 한다고 해도 전부다 새로 생성하는 것이 아니라 ui에서 바뀐 부분만 업데이트해주고 있다.

setState part One

useState는 우리한테 배열 하나를 주는데 첫번째 요소는 우리가 담으려는 data값이고 두번째 요소는 data값을 바꿀 때 사용할 modifier이다.

setState part Two


하나의 함수와 한줄의 코드로 전의 복잡한 방법을 완전히 대체했다.

State Functions

사용자들의 input을 어떻게 얻는지 form을 만들었을 때 state는 어떤식으로 작용하는지에 대해 배운다.

만약 현재 state를 바탕으로 다음 state를 계산하고 싶다면
setCounter((current) => current +1); 이렇게 사용해야한다.

Inputs and State

Unit conversion(단위변환) 앱을 만들 것이다.
Jsx는 html과 비슷하지만 다른 점 몇가지가 있다. 예를 들면 class 대신 className이라고 써줘야 한다. for도 htmlFor이라고 써줘야 한다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/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 [minutes, setMinutes] = React.useState();
      const onChange = (event) => {
        setMinutes(event.target.value);
      };
      return (
        <div>
          <h1 className="hi">Super Converter</h1>
          <label htmlFor="minutes">Minutes</label>
          <input
            value={minutes}
            id="minutes"
            placeholder="Minutes"
            type="number"
            onChange={onChange}
          />
          <h4>You want to convert {minutes}</h4>
          <label htmlFor="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number" />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>

State Practice part One

모든게 리랜더링 되는게 아니라 value부분만 다시 렌더링 한다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/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 [minutes, setMinutes] = React.useState();
      //첫번째 요소는 데이터, 두번째는 데이터 수정을 위한 함수
      const onChange = (event) => {
        setMinutes(event.target.value);
      };
      const reset = () => setMinutes(0);
      return (
        <div>
          <h1>Super Converter</h1>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={minutes} //state로 연결. 어디서든 input의 value를 수정해 줄 수 있다.
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              //데이터를 업데이트 해주는 역할. 사용자가 input에 뭘 쓸 때 onchang가 실행된다
            />
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={Math.round(minutes / 60)} //반올림
              id="hours"
              placeholder="Hours"
              type="number"
              disabled //minutes부분에만 쓸 수 있고 hours부분은 막아놓는 것이다.
            />
          </div>
          <button onClick={reset}>Reset</button>
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>

State Practice part Two

단위 변환을 뒤집어보는 함수(flip function)을 만들어본다. 클릭하면 Hours를 enabled(입력가능)하게 해주고 반대로 Minutes은 disabled하게 만들어 줄 것이다. 다시 클릭하면 반대로 되도록 한다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/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();
      //첫번째 요소는 데이터, 두번째는 데이터 수정을 위한 함수
      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>
          <h1>Super Converter</h1>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={flipped ? amount * 60 : amount} //state로 연결. 어디서든 input의 value를 수정해 줄 수 있다.
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              //데이터를 업데이트 해주는 역할. 사용자가 input에 뭘 쓸 때 onchang가 실행된다
              disabled={flipped}
            />
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={flipped ? amount : Math.round(amount / 60)} //반올림
              //만약 flipped 상태라면 state에 있는 값을 그대로 보여주는 것. 아니라면 변환된 값 보여줘
              id="hours"
              placeholder="Hours"
              type="number"
              disabled={!flipped} //minutes부분에만 쓸 수 있고 hours부분은 막아놓는 것이다.
              onChange={onChange}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>Flip</button>
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>

Recap

최종코드

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/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();
      //첫번째 요소는 데이터, 두번째는 데이터 수정을 위한 함수
      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>
          <h1>Super Converter</h1>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={inverted ? amount * 60 : amount} //state로 연결. 어디서든 input의 value를 수정해 줄 수 있다.
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              //데이터를 업데이트 해주는 역할. 사용자가 input에 뭘 쓸 때 onchang가 실행된다
              disabled={inverted}
            />
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={inverted ? amount : Math.round(amount / 60)} //반올림
              //만약 flipped 상태라면 state에 있는 값을 그대로 보여주는 것. 아니라면 변환된 값 보여줘
              id="hours"
              placeholder="Hours"
              type="number"
              disabled={!inverted} //minutes부분에만 쓸 수 있고 hours부분은 막아놓는 것이다.
              onChange={onChange}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onInvert}>
            {inverted ? "Turn back" : "Invert"}
          </button>
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>

Final practice and Recap

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function MinutesToHours() {
      const [amount, setAmount] = React.useState();
      //첫번째 요소는 데이터, 두번째는 데이터 수정을 위한 함수
      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>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={inverted ? amount * 60 : amount} //state로 연결. 어디서든 input의 value를 수정해 줄 수 있다.
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              //데이터를 업데이트 해주는 역할. 사용자가 input에 뭘 쓸 때 onchang가 실행된다
              disabled={inverted}
            />
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={inverted ? amount : Math.round(amount / 60)} //반올림
              //만약 flipped 상태라면 state에 있는 값을 그대로 보여주는 것. 아니라면 변환된 값 보여줘
              id="hours"
              placeholder="Hours"
              type="number"
              disabled={!inverted} //minutes부분에만 쓸 수 있고 hours부분은 막아놓는 것이다.
              onChange={onChange}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onInvert}>
            {inverted ? "Turn back" : "Invert"}
          </button>
        </div>
      );
    }
    function KmToMiles() {
      return <h3>KM 2 M</h3>;
    }
    function App() {
      const [index, setIndex] = React.useState("xx"); //data,data수정 funciton
      const onSelect = (event) => {
        setIndex(event.target.value);
      };
      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 units" : null}
          {index == "0" ? <MinutesToHours /> : null}
          {index == "1" ? <KmToMiles /> : null}
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>
profile
일단 해보자고

0개의 댓글