[React #24] COUNTER APP 만들기

    반응형

    01. 직접 짠 코드

    📑 Header.jsx

    const Header = () => {
      return (
        <div>
          <h1>Simple Counter</h1>
        </div>
      );
    };
    
    export default Header;

     

    📑 Viewer.jsx

    import { useState } from "react";
    
    const Viewer = () => {
      const [count, setCount] = useState(0);
    
      const countHandler = (e) => {
        setCount(count + parseInt(e.target.innerText));
      };
    
      return (
        <div>
          <p>현재 카운트 :</p>
          <h3>{count}</h3>
          <div>
            <button onClick={countHandler}>-1</button>
            <button onClick={countHandler}>-10</button>
            <button onClick={countHandler}>-100</button>
            <button onClick={countHandler}>+100</button>
            <button onClick={countHandler}>+10</button>
            <button onClick={countHandler}>+1</button>
          </div>
        </div>
      );
    };
    
    export default Viewer;

     

    📑 App.jsx

    import "./App.css";
    import Header from "./components/Header";
    import Viewer from "./components/Viewer";
    import Controller from "./components/Controller";
    
    function App() {
      return (
        <div className="app">
          <Header />
          <Viewer />
        </div>
      );
    }
    
    export default App;

    실행화면

    02. 수정 코드

     

    📑 App.jsx

    import "./App.css";
    import Viewer from "./components/Viewer";
    import Controller from "./components/Controller";
    import { useState } from "react";
    
    function App() {
      const [count, setCount] = useState(0);
    
      const countHandler = (value) => {
        setCount(count + value);
      };
    
      return (
        <div className="app">
          <h1>Simple Counter</h1>
          <section>
            <Viewer count={count} />
          </section>
          <section>
            <Controller countHandler={countHandler} />
          </section>
        </div>
      );
    }
    
    export default App;
    • section 태그로 컴포넌트를 묶는 이유 : 컴포넌트들마다 동일한 스타일을 주기 위함
    • App이 count 변수는 Viewr, setCount의 이벤트 핸들러는 Controller에게 전달

     

    📑 App.css

    body {
      padding: 20px;
    }
    
    .app {
      display: flex;
      flex-direction: column;
      gap: 10px;
      width: 500px;
      margin: 0 auto;
    }
    
    .app > section {
      background-color: rgb(245, 245, 245);
      border: 1px solid rgb(240, 240, 240);
      border-radius: 5px;
      padding: 20px;
      margin-bottom: 10px;
    }

     

    📑 Viewer.jsx

    const Viewer = ({ count }) => {
      return (
        <div>
          <p>현재 카운트 :</p>
          <h3>{count}</h3>
        </div>
      );
    };
    
    export default Viewer;

     

    📑 Controller.jsx

    const Controller = ({ countHandler }) => {
      return (
        <div>
          <button
            onClick={() => {
              countHandler(-1);
            }}
          >
            -1
          </button>
          <button
            onClick={() => {
              countHandler(-10);
            }}
          >
            -10
          </button>
          <button
            onClick={() => {
              countHandler(-100);
            }}
          >
            -100
          </button>
          <button
            onClick={() => {
              countHandler(100);
            }}
          >
            +100
          </button>
          <button
            onClick={() => {
              countHandler(10);
            }}
          >
            +10
          </button>
          <button
            onClick={() => {
              countHandler(1);
            }}
          >
            +1
          </button>
        </div>
      );
    };
    
    export default Controller;

     

    실행화면

     

     

     

     

    POINT 1 ⭐

     

    "데이터의 원천 state를 어떤 컴포넌트에 위치시킬지 생각하기"

     

    특정값을 변경시켰을 때, 변경된 값을 컴포넌트가 화면에 바로 렌더링 하려면 state로 만들어야 하는데,

    state는 컴포넌트 내부에서만 만들 수 있음

    또한 props를 이용해서 값을 전달할 때는, 부모와 자식 관계에서만 가능하고,

    형제 관계의 컴포넌트는 props를 이용해서 서로에게 값을 전달할 수 없음

     그래서 하나의 state를 여러 컴포넌트에서 관리하게 될 경우, 반드시 이 컴포넌트들의 공통 부모가 되는 곳에서 state를 만들어야 함

    리액트의 계층 구조

     

    여러 개의 컴포넌트들이 서로 부모와 자식 관계를 이루며 계층 구조를 형성하는데,

    특정 컴포넌트가 다른 컴포넌트에게 데이터를 전달할 때는 반드시
    두 컴포넌트는 서로 부모 자식 관계를 가지고 있어야 함
    props를 이용하여 데이터 전달은 부모에서 자식 방향으로만 가능

    ✅ state Lifting : 계층 구조상에서 위로 끌어올려 아래에 있는 컴포넌트들이 모두 공유할 수 있는 방법
    ✅ 단방향 데이터 흐름 : 데이터의 흐름이 위에서 아래의 방향으로 흐르기 때문에 직관적임

     


    POINT 2 ⭐

     

    "함수와 함께 인수를 전달한다면 콜백 함수로 전달하기"

     

    부모가 자식에게 props로 함수를 전달할 때, 인수도 전달하고 싶다면

    함수 즉시 호출인 onClick={countHandler}onClick={countHandler(-10)}  대신

    콜백 함수를 사용하여 onClick={()=>{countHandler(10}} 이렇게 전달해야 함

    → countHandler 함수를 이벤트 핸들러로 설정하고 해당 이벤트 헨들러에서 함수를 호출한 뒤 원하는 값의 인수를 넘겨야 함

     

     

     

     

    참고자료

    이정환 Winterlood, '한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지'
    반응형

    댓글