ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [team-project_종합 게임 사이트 만들기] 게임 별 탭 기능 구현
    Project/종합 게임 사이트 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]}</>;
    }

Designed by Tistory.