본문 바로가기

Libraries/React

[React] State 뜻, 카운터 함수, 예시

728x90

 

   목차 

1. State 란?
2. State로 카운터 함수 만들어보기
3. State를 세팅해주는 2가지 방법
4. State를 사용한 예시 (분→시간 변환기)

 

 

 State 란? 


- 계속해서 변화하는 특정 상태
- 상태에 따라 각각 다른 동작을 함 

 

 


 

 

 State로 카운터 함수 만들어보기 

 

Counter.jsx

const Counter = () => {
return (
  <div>
   <h2>0</h2> 
   <button>+</button>
   <button>-</button>
   </div>
  );
 };
 
 export default Counter;
- Counter 컴포넌트에서 동적으로 변화해야하는 유일한 값은 <h2>태그 사이에 있는 카운트 숫자 0임
- 카운트 숫자가 '상태'임
- 기본값이 0에서 출발하고 1씩 증가, 1씩 감소하는 Count 상태

 

 

import React,{useState} from 'react'; // state는 리액트의 기능이기 때문에, useState 메서드를 import

const Counter = () => {

const [count,setCount] = useState(0)

return (
  <div>
   <h2>{count}</h2> 
   <button>+</button>
   <button>-</button>
   </div>
  );
 };
 
 export default Counter;
- useState 메서드는 배열을 반환하고 배열의 비구조화할당을 통해서 0번째 인덱스 count, 1번째 인덱스 setCount라는 상수로 받아옴
- count는 상태의 값으로 사용이 됨 → 값이기 때문에 JSX에서 return해서 화면에 표시할수 있음
- setCount는 count라는 상태를 변화(업데이트)시키는 '상태변화함수'로서 사용함
- useState 메서드를 호출하면서 넘겨준 인자인 0은 우리가 count라는 상태를 만드는데 초기값으로 사용됨
- 0에서 출발한다는 소리임

 

 

 

 + 버튼 눌렀을때 1씩 증가 시키기 

 

import React,{useState} from 'react'; // state는 리액트의 기능이기 때문에, useState 메서드를 import

const Counter = () => {

const [count,setCount] = useState(0)

const onIncrease = () =>{      // 1씩 증가시키는 함수
  setCount(count + 1);         // 상태변화함수(setCount)에 인자로 새로운 상태를 전달하기
}

return (
  <div>
   <h2>{count}</h2> 
   <button onClick={onIncrease}>+</button>   // 버튼을 눌렀을 때 실행되게끔 하기
   <button>-</button>
   </div>
  );
 };
 
 export default Counter;

 

 

 

 

 - 버튼 눌렀을때 1씩 감소 시키기 

 

import styles from "./Counter.module.css";

import React,{useState} from 'react';

const Counter = () => {

const [count,setCount] = useState(0)

const onIncrease = () =>{      // 1씩 증가시키는 함수
  setCount(count + 1);         // 상태변화함수(setCount)에 인자로 새로운 상태를 전달하기
}

const onDecrease = () =>{      // 1씩 감소시키는 함수
  setCount(count -1);          // 상태변화함수(setCount)에 인자로 새로운 상태를 전달하기  
}

return (
  <div>
   <h2>{count}</h2> 
   <button onClick={onIncrease}>+</button> 
   <button onClick={onDecrease}>-</button>
   </div>
  );
 };
 
 export default Counter;

 

                               

 


 

 

 State를 세팅해주는 2가지 방법 

 

 

 (1) 직접 값을 설정해준다.  

const root = document.getElementById("root");

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.createRoot(root).render(<App />);
</script>
 
</html>
- setCounter 함수는 어떤 값을 부여하던 그 값으로 업데이트하고 리렌더링을 일으킨다. (App 함수가 다시 호출된다)
- 즉, setCounter 함수를 이용해서 state를 바꾸면, 컴포넌트(App함수)가 리렌더링 되고, 이 코드가 다시 실행된다.
- return도 한번 더 실행되지만, 새로운 값을 가지고 실행된다.
- 예컨대 counter를 1로 세팅하면 리렌더링이 일어나고, 다시 클릭하면 2가 된다.
- 왜냐하면 말 그대로 모든 요소를 새로운 값을 가지고 재생성하고있기 때문이다.
- 이 컴포넌트가 리렌더링될때 달라지는 부분은 {counter}뿐이며, 이벤트리스너가 또 등록되거나 Total click을 다시 만드는게 아니다. 

 

 

 

 (2) 함수를 전달한다. 

const root = document.getElementById("root");

function App () {
  const [counter, setCounter] = React.useState(0)
  const onClick = ()=> {
 setCounter((current)=> current+1); // 현재의 state를 가지고 새로운 값을 계산함 (current는 현재값임) 
  };
  return(
  <div>                   
    <h3>Total clicks: {counter}</h3>
    <button onClick={onClick}>Click me</button>
    </div>
  )
  };

  ReactDOM.createRoot(root).render(<App />);
</script>
 
</html>
- 현재 state를 바탕으로 다음 state를 계산해내고 싶다면, 함수를 사용해야한다.
- 현재 state는 현재 counter값이다.

 

 


 

 

 State를 사용한 예시: 분→시간 변환기 만들기 

 

 

 분→시간 변환 

function App () {
    const[minutes, setMinutes] = React.useState() //minutes는 value, setMinutes는 value를 수정하고, component를 새로고침할때 쓰는 함수 
    const onChange =(event) => {
setMinutes(event.target.value); //target은 방금바뀐 input을 말함. 열면 value가 있음 -> 이걸 minutes에 넣어주기 -> setState함수 사용 
    }                            // 입력한 input의 value를 바탕으로 component를 업데이트해줌
  return(
  <div>                   
    <h1>Super Converter</h1>
    <div>
    <label htmlFor="minutes">Minutes</label>
    <input value={minutes} id="minutes" placeholder="Minutes" type="number" onChange={onChange}/>
  </div>
  <div>
    <label htmlFor="hours">Hours</label>
    <input value={Math.round(minutes/60)} id="hours" placeholder="Hours" type="number"/>
    </div>
    </div>
    );
  };
  
  const root = document.getElementById("root");
  ReactDOM.createRoot(root).render(<App />);

 

 

 

 리셋 버튼 만들기 

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} id="minutes" placeholder="Minutes" type="number" onChange={onChange}/>
  </div>
  <div>
    <label htmlFor="hours">Hours</label>
    <input  value={Math.round(minutes/60)} id="hours" placeholder="Hours" type="number"/>
    </div>
    <button onClick={reset}>Reset</button> // 리셋 버튼
    </div>
    );
  };
  
  const root = document.getElementById("root");
  ReactDOM.createRoot(root).render(<App />);

 

 

 

 

 flip 기능 추가하기 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <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(0); 
			//minutes는 value, setMinutes는 value를 수정하고, component를 새로고침할때 쓰는 함수
      const [flipped, setFlipped] = React.useState(false); 
			// flipped는 true 혹은 false인 변수

      const onChange = (event) => {
        setMinutes(event.target.value); 
      const reset = () => setMinutes(0);
      const onFlip = () => setFlipped((current) => !current); 
			// 현재 값을 받아서 그 반대의 값을 내놓음 (true<->false)
      return (
        <div>
          <h1>Super Converter</h1>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={minutes}
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              disabled={flipped === true} // flipped가 true라면 disabled는 true가 돼야함 = Hours가 disabled 됨 
            />
            
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={Math.round(minutes / 60)}
              id="hours"
              placeholder="Hours"
              type="number"
              disabled={flipped === false}
             // flipped가 false라면 disabled는 true가 돼야함 (처음에 기본값일때, hours는 안보이게끔)
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>Flip</button>  // flip 버튼 누르면 onFlip함수가 실행됨
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.createRoot(root).render(<App />);
  </script>
</html>

 

 

 

참고 자료 

- 인프런: 한입 크기로 잘라 먹는 리액트
- 노마드코더: 리액트로 영화 웹 서비스 만들기

728x90