Project/[Team]종합 게임 사이트

[team-project_종합 게임 사이트 만들기] 게임 별 탭 기능 구현

dbfl9911 2023. 10. 22. 20:28
반응형

팀 프로젝트 회의 결과 4가지 간단한 게임을 할 수 있는 종합 게임 사이트를 만들기로 하였다. 

 

[ 오늘의 작업 과정 ]

1. 전체적인 UI 디자인

2. 상단의 탭을 눌렀을 때 게임별로 보여지는 기능 구현하기

 

 리액트를 사용하였고 탭, 버튼 부분 등은 리액트 부트스트랩을 활용하였다. 

 

1. 게임 시작 화면 구현 (App.js)

- useNavigate()를 사용해 버튼 클릭시 게임 화면(/game)으로 넘어가도록 구현했다. 첫 시작 화면은 시작할 때 한번 빼고는 공통으로 자주 쓰일 일이 없다고 판단해 따로 Content() 컴포넌트로 사용하기로 하였다. 

function Content() {
  let navigate = useNavigate();

  return (
    <div className="start">
      <h2>종합 게임 즐기기</h2>
      <Button
        variant="primary"
        className="start"
        onClick={() => {
          navigate("/game");
        }}
      >
        시작하기
      </Button>
    </div>
  );
}

2. Route 컴포넌트 사용해 경로별로 페이지 보여지도록 구현 (App.js)

- 따로 routes 폴더를 만들어 게임별로 4개의 js 파일을 만들었고 이 역시 컴포넌트화해서 App.js에서 사용하기로 하였다. 

- 첫 홈페이지 부분, 각각의 4가지 게임이 보여지는 페이지 부분은 Routes, Route 컴포넌트를 사용해 경로별로 화면이 보여지도록 구현했다. 

import { Route, Routes, useNavigate } from "react-router-dom";

function App() {

  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Content />} /> // 첫 게임 시작 화면
        <Route
          path="/game"
          element={
            <div className="webView">
              <header>
                <h2>종합 게임</h2>
                // 종합 게임 화면 페이지 부분

3. 탭 기능 구현하기

- useState() 함수를 사용해 각 게임별로 탭을 눌렀을 때의 상태를 넣기로 하였다. 초깃값은 0으로 게임별로 클릭시 각각의 상태를 숫자형태(1,2,3,4)로 setTab()에 넣었다. 

function App() {
  let [tab, setTab] = useState(0);

  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Content />} />
        <Route
          path="/game"
          element={
            <div className="webView">
              <header>
                <h2>종합 게임</h2>
              </header>
              <div className="main">
                <div className="main_content">
                  <Nav variant="tabs" className="nav-justified">
                    <Nav.Item>
                      <Nav.Link onClick={() => setTab(0)} eventKey="link0">
                        지뢰찾기
                      </Nav.Link>
                    </Nav.Item>
                    <Nav.Item>
                      <Nav.Link onClick={() => setTab(1)} eventKey="link1">
                        오목(2인용)
                      </Nav.Link>
                    </Nav.Item>
                    <Nav.Item>
                      <Nav.Link onClick={() => setTab(2)} eventKey="link2">
                        스네이크
                      </Nav.Link>
                    </Nav.Item>
                    <Nav.Item>
                      <Nav.Link onClick={() => setTab(3)} eventKey="link3">
                        오셀로(2인용)
                      </Nav.Link>
                    </Nav.Item>
                  </Nav>
                  <div className="tab_content">
                    <TabContent tab={tab} />
                  </div>
                </div>
                ...

- 위에서 만들었던 게임별 컴포넌트를 탭을 누를 때마다 보여지도록 구현해야 한다. 이를 위해 따로 App.js에 TabContent() 함수를 만들어 탭 상태가 바뀔때마다 각각의 게임별 컴포넌트가 보여지도록 하였다. 

- 부모 컴포넌트 App에 있던 state인 tab을 사용해야하므로 자식 컴포넌트인 TabContent()에서 props로 전송해서 사용해야 한다. 

function App() {
  let [tab, setTab] = useState(0);

  return (
      ....
                  <div className="tab_content">
                    <TabContent tab={tab} />
                  </div>
	  ....
}

function TabContent(props) {
  return <>{[<Game1 />, <Game2 />, <Game3 />, <Game4 />][props.tab]}</>;
}

 

[ Trouble-shooting ]

- 사실 문제라기보다는 코드를 좀 간단하게 구현하고 싶어서ㅎㅎ. TabContent() 함수 부분에서 말이다. 위의 코드처럼 간단하게 구현하기 이전의 코드이다. 

  function TabContent(props){ 
    if (props.tab == 0){
      return <Game1/>
    }
    if (props.tab == 1){
      return <Game2/>
    }
    if (props.tab == 2){
      return <Game3/> 
    }  
    if (props.tab == 3){
      return <Game4/>
    }
  }

- 물론 정상적으로 잘 구현되지만 코드를 줄여보고 싶었다..!

if문 대신 array 자료형을 사용해 탭 클릭에 따라 화면이 보여지도록 구현해 상단의 코드를 한줄로 깔끔하게 줄였다. props.tab이 0이면 array 자료에서 0번째 게임을 꺼내 보여준다. 

function TabContent(props) {
  return <>{[<Game1 />, <Game2 />, <Game3 />, <Game4 />][props.tab]}</>;
}

- 아래처럼 props를 쉽게 쓰는 방법도 있다. props라고 파라미터를 하나만 작명하는게 아니라 {state이름} 이렇게 써도 정상적으로 작동한다. 

function TabContent({tab}) {
  return <>{[<Game1 />, <Game2 />, <Game3 />, <Game4 />][tab]}</>;
}

반응형