본문 바로가기

블록체인_9기/🩵 React

47강_230705_React(Router, 가위바위보 제작)

728x90

 

 

 

 


React_useEffect / useState 이용해서 가위바위보 제작

제작조건

  • 플레이어는 유저와 컴퓨터이다.
  • 유저의 패는 게임을 하는 사람이 선택할 수 있고, 컴퓨터의 패는 랜덤으로 지정된다.

 

1. App.js_전체 화면을 그리고 전체 기능을 구현한다.

  • select함수 : 컴퓨터와 유저가 가위바위보의 패를 냈을 때 보여줄 그림을 지정한다.
  • useState
    • setUserSelect : 유저가 선택한 패를 담아준다.
    • setComSelect : 컴퓨터의 선택 값을 담아준다.
    • setResult : 승패 결과를 담는다.
  • userClick함수 : 유저가 패를 클릭하면 해당 패의 값을 setUserSelect 에 전달한다.
  • Object.keys (): 매개변수의 키 값만 뽑아서 배열로 반환해준다. 따라서 arr은 가위바위보 패를 배열로 담는다.
  • ComRandom : 0 ~ 2까지의 정수 값을 담아 arr의 배열에서 랜덤한 값을 뽑는다.
  • return(): Block 컴포넌트에  유저가 선택한 값과 컴퓨터가 선택한 값을 보내준다.
import { useEffect, useState } from "react";
import "./App.css";
import Block from "./components/Block";
import { img01, img02, img03 } from "./img";

function App() {
  // select - 컴퓨터와 유저가 가위 바위 보를 냈을 때 필요한 데이터들을 모아둘 객체이다.
  const select = {
    scissors: {
      name: "가위",
      img: img01,
    },
    rock: {
      name: "바위",
      img: img02,
    },
    paper: {
      name: "보",
      img: img03,
    },
  };

  // 유저가 선택한 데이터 값은 주시하자.
  // 선택하면 데이터가 바뀐 상태로 다시 그려줘야 하기 때문에

  // 유저의 선택 useState
  const [userSelect, setUserSelect] = useState(null);
  // 컴퓨터의 선택 값을 담을 useState
  const [comSelect, setComSelect] = useState(null);
  // 승패 결과를 담을 useState
  const [result, setResult] = useState("");


  function userClick(_select) {

    // 선택한 객체를 상태변수에 담아주자
    setUserSelect(select[_select]);

    // 컴퓨터는 랜덤으로 선택을 시켜야하는데
    // 컴퓨터의 랜덤 값은 플레이어 선택 이후에 나와야 한다.

    // Object.keys: 매개변수의 객체 키값만 뽑아서 배열로 반환해준다.
    let arr = Object.keys(select);

    // 소숫점 제외시키고 랜덤한 정수 값 0 ~ 2를 출력
    let ComRandom = Math.floor(Math.random() * 3);

    // ComRandom - 랜덤한 값 0~2
    // arr = ['scissors', 'rock', 'paper']
    // arr[ComRandom] = 'scissors', 'rock', 'paper'
    // select[arr[ComRandom]] : select 객체에 arr로 뽑아낸 키 값을 넣어 어떤 패가 선택되었는지 보여준다.
    setComSelect(select[arr[ComRandom]]);

    // 승패 결과값을 내보내자
    let player = select[_select];
    let Computer = select[arr[ComRandom]];

    // 처음에 무승부 거르고
    if (player.name === Computer.name) {
      setResult("무승부");
    } else if (player.name == "가위") {
      let result = Computer.name == "보" ? "승리" : "패배";
      setResult(result);
    } else if (player.name == "바위") {
      let result = Computer.name == "가위" ? "승리" : "패배";
      setResult(result);
    } else if (player.name == "보") {
      let result = Computer.name == "바위" ? "승리" : "패배";
      setResult(result);
    }
  }

  useEffect(() => {
    console.log(userSelect);
  }, [userSelect]);

  return (
    <>
      <div className="App">
        <Block data={userSelect} name={"유저"} result={result} />
        <Block data={comSelect} name={"컴퓨터"} result={result} />
      </div>
      <div>
        {/* 버튼은 여기에 */}
        <button
          onClick={() => {
            userClick("scissors");
          }}
        >
          ✌️
        </button>
        <button
          onClick={() => {
            userClick("rock");
          }}
        >
          ✊
        </button>
        <button
          onClick={() => {
            userClick("paper");
          }}
        >
          ✋
        </button>
      </div>
    </>
  );
}

export default App;

 

2. App.js_가위바위보 결과값 받아와 승패 여부를 판단하여 그려준다.

import React from "react";

const Block = ({ data, name, result }) => {
  let temp = "";
  if (name == "유저") {
    temp = result;
  } else {
    // result == "무승부"면 문제가 없으니 놔둬도 괜찮다.
    // result == "승리"면 반대로 패배를 보여줘야 하고,
    // result == "패배"면 반대로 승리를 보여줘야 한다.

    // 무승부를 제외한 결과값은 유저와 컴퓨터가 서로 반대의 값을 출력해야 한다.
    // 결과 값이 무승부면? 무승부를 출력한다. 아니면 다시 결과 값을 확인한다.
    // 다시 확인한 결과값이 승리면? 패배를 출력한다. 아니면 값이 패배일 것이므로 패배면 승리를 출력한다.
    temp = result === "무승부" ? "무승부" : result === "승리" ? "패배" : "승리";
  }

  return (
    <div className="block">
      <div>{name}</div>
      {/* 리액트애서 가장 많이 사용하는 조건부 렌더링. 값이 있으면 값을 사용해라라는 구문이다. */}
      {/* 값이 없으면 페이지가 터지기 때문에 설정한다. */}
      <img src={data && data.img} alt="가위바위보" />
      <div>{temp}</div>
    </div>
  );
};

export default Block;

 

 

 

 


React Router

🙄 라우팅??

  • 웹 애플리케이션에서 라우팅의 개념은 사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것을 의미한다.

 

🙄 React Router?

  • SPA로 하나의 HTML로 페이지를 보여준다.
  • 페이지를 컴포넌트로 구성하고, 하위 컴포넌트들을 모아서 페이지 형태로 구색을 맞춰 브라우저에 보여준다.
  • 페이지가 전환되는 것은 페이지 컴포넌트 조건마다 바꿔서 보여준다.
  • 이때, 브라우저는 새로고침 되지 않고 내용만 교체시키도록 한다.

 

🙄 Routes? Route? 

  • Routes
    • Route의 복수형으로 Route를 묶어주는 역할을 한다.
      • 기존에는 switch의 역할이었지만 버전이 달라지면서 Routes로 변경되었다.
    • Route들의 부모 컴포넌트이다.
  • Route
    • 화면의 전환을 담당한다.
    • 컴포넌트 페이지를 정의해준다.
    • 속성
      • path : 브라우저의 경로 ( 컴포넌트 페이지를 바꿔서 보여줄 경로이다.)
      • element : path경로에 브라우저 경로가 맞으면 이 속성에 넣은 컴포넌트를 보여준다.

 

React Router 사용하기

1. React Router 설치

  • 터미널에 npm install react-router-dom@6 입력하여 설치
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  // BrowserRouter 컴포넌트로 App 컴포넌트를 자식으로 감싸서 App 컴포넌트가 라우팅 기능을 사용할 수 있다.
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

 

2. pages/Main.jsx, Login.jsx, Shop.jsx_필요한 페이지 단위별로 jsx를 생성하고 Link 컴포넌트로 보여지는 컴포넌트를 변경한다.

  • 페이지는 간단하게 생성하였으므로, 예시 중 하나로 Main.jsx를 소개하고자 한다.

💡 Link 컴포넌트

  • 클릭 시 다른 주소(컴포넌트)로 이동시킨다.
  • 페이지 전환(새로고침)이 없다.
  • a태그와 유사한 기능을 한다.
import React from "react";
import { Link } from "react-router-dom";

const Main = () => {
  return (
    <div>
      메인페이지
      {/* a태그를 반환해준다. 페이지 전환이 없이 링크에 걸린 컴포넌트로 이동된다. */}
      <Link to={"/shop"}>상점으로 이동</Link>
    </div>
  );
};

export default Main;

 

3. App.js_조건부 렌더링을 통해 조건에 맞는 경로로 이동하여 해당 조건에 맞는 컴포넌트를 노출시킨다.

import "./App.css";
import { Login, Main, Shop } from "./pages";
import { Routes, Route } from "react-router-dom";

function App() {
  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Main />} />
        <Route path="/login" element={<Login />} />
        <Route path="/shop" element={<Shop />} />
      </Routes>
    </div>
  );
}

export default App;

 

 

 

 

 

 

 

 

 

728x90