본문 바로가기

React

[React 기초] 02. State

State

  • state: 데이터가 저장되는 곳
  • 아래 예시에서 counter의 숫자 부분을 state로 대체 가능
  • 버튼을 누를 때 전체가 render되게 됨
  • 이렇게 구현해도 개발자 도구로 버튼을 누를 때마다 바뀌는 부분을 확인하면, 해당 부분 숫자만 바뀌는 것을 확인할 수있음 - react 짱
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Begin React</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/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);
    }
    const Container = () => (
      <div>
        <h3>Total clicks: {counter}</h3>
        <button onClick={countUp}>Click me</button>
      </div>
    );
    ReactDOM.render(<Container />, root);
  </script>
</html>
조금 더 rendering을 편하게 하는 방법은 없을까?

useState

[추가팁] JS 문법 
const food = ["tomato", "potato"];
const [myFavFood, mySecondFavFood] = food;
// same as myFavFood = food[0];, mySecondFavFood = food[1];
// myFavFood
// 'tomato'
useState를 사용해서 바뀐 부분과 함께 render
const [counter, setCounter] = React.useState(0);
const onClick = () => {
// modifier function은 값을 변화시킨 다음에 rerender 시켜줌
setCounter(counter + 1);
};
modifier function alpha; 변수를 통한 직접적인 값 변화보다는 함수로 처리하는 것이 더 안전
const [counter, setCounter] = React.useState(0);
const onClick = () => {
  // modifier function은 값을 변화시킨 다음에 rerender 시켜줌
  // setCounter(counter + 1);
  setCounter((current) => current + 1);
};

최종 코드

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Begin React</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => {
        // modifier function은 값을 변화시킨 다음에 rerender 시켜줌
        // setCounter(counter + 1);
        setCounter((current) => current + 1);
      };
      return (
        <div>
          <h3>Total clicks: {counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

유의 사항

JSX를 사용할 때는 JSX에 맞는 프로퍼티를 사용해야 함

  • class -> className
  • for -> htmlFor

React는 SyntheticBaseEvent를 발생시킴, 그 안에 nativeEvent 속성 값이 있음


분을 시간으로 환산해주는 계산기 만들어보기

  • minutes에 값을 입력하면 hour로 변환
  • input에 값을 입력 시, onChange 이벤트가 발생
  • onChange 이벤트는 setMinutes()를 작동
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Begin React</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [minutes, setMinutes] = React.useState(0);
      const onChange = (event) => {
        // console.log(event.target.value);
        setMinutes(event.target.value);
      };
      const reset = () => setMinutes(0);
      return (
        <div>
          <h1>Super Converter</h1>
          <label htmlFor="minutes">Minutes</label>
          <input
            id="minutes"
            placeholder="Minute"
            type="number"
            value={minutes}
            onChange={onChange}
          />
          <br></br>
          <label htmlFor="hours">Hours</label>
          <input
            id="hours"
            placeholder="Hours"
            type="number"
            disabled
            value={Math.round(minutes / 60)}
          />
          <br></br>
          <button onClick={reset}>Reset</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

시간도 분으로 계산할 수 있도록 개선해보기

  • hour input 태그에도 onChange 함수 적용
  • onFlip 이라는 변수로 현재 flipped된 상태인지 아닌지 구분
  • tenary syntax로 onFlip 변수의 상태마다 value 값이 다르게 출력될 수 있도록 함
  • tenary syntax로 onFlip 변수의 상태마다 disabled가 적용될 수 있도록 함
  • tenary syntax로 onFlip 변수의 상태마다 button의 value 값이 적용될 수 있도록 함
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Begin React</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [amount, setAmount] = React.useState(0);
      const [flipped, setFlipped] = React.useState(false);
      const onChange = (event) => {
        // console.log(event.target.value);
        setAmount(event.target.value);
      };
      const reset = () => setAmount(0);
      // const onFlip = () => setflip(!flipped);
      const onFlip = () => {
        setFlipped((current) => !current);
        reset();
      };
      return (
        <div>
          <h1>Super Converter</h1>
          <label htmlFor="minutes">Minutes</label>
          <input
            id="minutes"
            placeholder="Minute"
            type="number"
            onChange={onChange}
            value={flipped ? amount * 60 : amount}
            disabled={flipped}
          />
          <br></br>
          <label htmlFor="hours">Hours</label>
          <input
            id="hours"
            placeholder="Hours"
            type="number"
            onChange={onChange}
            value={flipped ? amount : Math.round(amount / 60)}
            disabled={flipped === false}
          />
          <br></br>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>
            {flipped ? "Minutes to Hours" : "Hours to Minutes"}
          </button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

Class 사용 예시

import React from "react";

class App extends React.Component {
  state = {
    count: 0,
  };
  plus = () => {
    this.setState((current) => ({ count: current.count + 1 }));
  };
  minus = () => {
    this.setState((current) => ({ count: current.count - 1 }));
  };
  render() {
    return (
      <div>
        <h1>The number is {this.state.count}</h1>
        <button onClick={this.plus}>plus</button>
        <button onClick={this.minus}>minus</button>
      </div>
    );
  }
}

export default App;

'React' 카테고리의 다른 글

[React 기초] 06. 예제 - Todo List  (0) 2023.08.10
[React 기초] 05. effects  (0) 2023.08.10
[React 기초] 04. create-react-app  (0) 2023.08.10
[React 기초] 03. Props  (0) 2023.08.02
[React 기초] 01. Basics of React JS  (0) 2023.08.02