프론트엔드/React

[React] 4. State

sujin7837 2022. 11. 22. 23:27
반응형

State

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="root"></div>
  </body>
  <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script crossorigin 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">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp() {
      counter = counter + 1;
      render();
    }

    function render() {
      ReactDOM.render(<Container />, root);
    }
    function Container() {
       return (
        <div>
          <h3>Total clicks : {counter}</h3>
          <button onClick={countUp}>Click me</button>
        </div>
      );
    }
    render();
  </script>
</html>

위 코드를 실행하고 브라우저의 개발자 도구 Elements에서 소스 코드를 확인해보면, h3, button, div들은 업데이트되지 않고 UI에서 바뀐 부분만 업데이트 해주는 것을 알 수 있습니다. 즉, React.js는 이전에 렌더링된 컴포넌트가 어떤건지 확인하고 다음에 렌더링될 컴포넌트가 무엇인지를 확인하여 다른 부분만 파악합니다. 따라서 모든 컴포넌트를 리렌더링할 필요 없이, 바뀐 부분만 다시 렌더링한다는 장점을 가지고 있습니다.

 

배열 쉽게 사용하기

const food = ["tomato", "potato"]

// 기존 코드
// tomato -> 'tomato'
// potato -> 'potato'
const tomato = food[0];
const potato = food[1];


// 간단한 코드
// myFavFood -> 'tomato'
// mySecondFavFood > 'potato'
const [myFavFood, mySecondFavFood] = food;

 

state 사용하기

React.useState() -> [변수, 함수]

ex) const [counter, setCounter] = React.useState(0);

       counter는 변수, setCounter 함수로 사용이 가능합니다.

 

따라서 state의 함수를 이용하여 렌더링을 손쉽게 구현할 수 있게 됩니다. 함수 내에 코드를 작성하여 코드가 바뀔 때마다 컴포넌트를 리렌더링하고 UI를 refresh할 수 있게 해줍니다. 가장 중요한 것은 state가 바뀌면 리렌더링이 일어난다는 것입니다.

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="root"></div>
  </body>
  <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script crossorigin 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">
    const root = document.getElementById("root");
    let counter = 0;

    function App() {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => {
        setCounter(counter + 1);
      };
      return (
        <div>
          <h3>Total clicks : {counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

 

Inputs and State

js 문법

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="root"></div>
  </body>
  <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script crossorigin 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() {
      return (
        <div>
          <h1 class="hi">Super Converter</h1> 
          <label for="minutes">Minutes</label> 
          <input id="minutes" placeholder="Minutes" type="number" />
          <label for="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number" />
        </div>
      )
    }
      const root = document.getElementById("root");
      ReactDOM.render(<App />, root);
  </script>
</html>

 

jsx 문법

1) script : production.min.js -> development.js

2) class -> className

3) for -> htmlFor

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="root"></div>
  </body>
  <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function App() {
      return (
        <div>
          <h1 className="hi">Super Converter</h1> 
          <label htmlFor="minutes">Minutes</label> 
          <input id="minutes" placeholder="Minutes" type="number" />
          <label htmlFor="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number" />
        </div>
      )
    }
      const root = document.getElementById("root");
      ReactDOM.render(<App />, root);
  </script>
</html>

 

input에서 value와 함수 이용하기

{ } 안에 state의 value 혹은 함수를 넣어주면 state를 활용한 다양한 기능을 만들 수 있습니다.

아래 예시에서는 시간 <-> 분 단위 변환하는 기능을 구현하고 있습니다.

<!DOCTYPE html>
<html lang="en">
<body>
  <div id="root"></div>
</body>
<script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.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 onInvert = () => {
      reset();
      setInverted((current) => !current);
    }

    return (
      <div>
        <h1 className="hi">Super Converter</h1> 
        <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 : Math.round(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>
    )
  }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
</script>
</html>

 

Component and State

화면에 렌더링되는 과정은 App 컴포넌트를 통해 이뤄집니다. 따라서 브라우저에 화면을 띄우기 위해서는 App.js에 존재해야 합니다.

MinutesToHours 라는 컴포넌트를 만들고, App에 넣어주어 렌더링할 수 있습니다. 이것을 이용하여 select 박스를 만들고, 원하는 항목을 선택하였을 때 선택된 것만 렌더링되도록 하는 기능도 만들어줄 수 있습니다.

<!DOCTYPE html>
<html lang="en">
<body>
  <div id="root"></div>
</body>
<script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
  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>
          <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 : Math.round(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>
      )
    }
  function KmToMiles() {
    return <h3>KM 2 M</h3>
  }
  function App() {
    const [index, setIndex] = React.useState("xx");
    const onSelect = (event) => {
      setIndex(event.target.value);
    } 
    console.log("render w/", index);
    return (
      <div>
        <h1 className="hi">Super Converter</h1> 
        <select name="" id="" 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>
    )
  }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
</script>
</html>

 

 

 

출처 : https://nomadcoders.co/react-for-beginners/lectures/3275

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

반응형

'프론트엔드 > React' 카테고리의 다른 글

[React] 6. Memo  (0) 2022.12.04
[React] 5. Props  (0) 2022.12.04
[React] 3. JSX  (0) 2022.11.13
[React] 2. Before React  (0) 2022.11.13
[React] 1. React 설치 및 환경세팅  (0) 2022.11.08