-
Router의 Link, Switch, historyReact 2022. 3. 15. 13:45
앞과 같이 상세페이지를 만들었다.
<Route path="/detail"> <div className="container"> <div className="row"> <div className="col-md-6"> <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" /> </div> <div className="col-md-6 mt-4"> <h4 className="pt-5">상품명</h4> <p>상품설명</p> <p>120000원</p> <button className="btn btn-danger">주문하기</button> </div> </div> </div> </Route>
이렇게 긴 상세페이지를 component화 해서 함수로 만든 후, 한단어로 쓸 수 있다.
function Detail() { return ( <div className="container"> <div className="row"> <div className="col-md-6"> <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" /> </div> <div className="col-md-6 mt-4"> <h4 className="pt-5">상품명</h4> <p>상품설명</p> <p>120000원</p> <button className="btn btn-danger">주문하기</button> </div> </div> </div> ) } //function App밖에 이렇게 만들고, 상세페이지에 Detail() 쓰면 된다.
그리고 다른 파일로 빼서 만들 수도 있다. 파일 이름을 Detail.js로 만든 후, 컴포넌트 파일을 만들 땐 import React를 해와야 한다.
import React, {useState} from 'react'; function Detail() { return ( <div className="container"> <div className="row"> <div className="col-md-6"> <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" /> </div> <div className="col-md-6 mt-4"> <h4 className="pt-5">상품명</h4> <p>상품설명</p> <p>120000원</p> <button className="btn btn-danger">주문하기</button> </div> </div> </div> ) }; export default Detail;
이렇게 export를 써주고 app.js에
import Detail from './Detail'; function App() { return ( <Route path="/detail"> <Detail /> </Route> ) }
이렇게 간단하게 줄일 수 있다. 이런 과정을 모듈화라고 부른다.
이번엔, 주소창에 /detail을 입력해서 이동하지 말고, 버튼을 누르면 메인페이지와 상세페이지로 가는 버튼을 만들어보자.
<Nav.Link ><Link to="/">Home</Link></Nav.Link> <Nav.Link ><Link to="/detail">Detail</Link></Nav.Link> //Nav.Link와 Link가 겹치면 a태그가 중복된걸로 감지해 콘솔창에 에러가 뜬다 //이럴땐 <Nav.Link as={Link} to="/detail">Detail</Nav.Link> //이렇게 부트스트랩의 link로 축약해주면 된다. 그리고 as={Link}를 써서 Link의 역할을 하게하면 된다.
이렇게 Link태그에 to를 이용해 적어주면 Home을 누르면 / (메인페이지)로 Detail을 누르면 /detail(상세페이지)로 이동한다. 물론 상단에 import {Link} from 'react-router-dom';을 작성해야 한다.
그리고 Link를 이용하지 말고, 페이지를 버튼으로 이동하는 방법도 있다.
먼저, detail페이지에 뒤로가기 버튼을 만들고 history훅을 이용한다.
그리고 따로 만들어 놓은 detail.js 파일에
import React, {useState} from 'react'; import { useHistory } from 'react-router-dom'; function Detail() { let history = useHistory(); //방문기록 등을 저장해놓는 object return ( <div className="container"> <div className="row"> <div className="col-md-6"> <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" /> </div> <div className="col-md-6 mt-4"> <h4 className="pt-5">상품명</h4> <p>상품설명</p> <p>120000원</p> <button className="btn btn-danger">주문하기</button> <button className="btn btn-danger" onClick={ () => { history.goBack();//뒤로가는 함수 //history.push('경로')이렇게하면 특정경로로 이동시킴 } }>뒤로가기</button> </div> </div> </div> ) } export default Detail;
이렇게 상단에 useHistory를 import해주고 let history = useHistory();를 적어주면 훅을 사용할 수 있다. 그러고 버튼을 onClick하면 history훅을 이용해 history.goBack();함수를 작성해주면 뒤로 갈 수 있다.
마지막으로, switch에 대해 알아보자
리액트는
<Route exact path="/"> <div className="jumbotron"> <h1>20% Season Off</h1> <p>fdsfsdf</p> <button className="btn btn-primary">Learn more</button> </div> <div className="container"> <div className="row"> { shoes.map( (a,i) => { return <ShopList shoes={shoes[i]} i={i} key={i}/> }) } </div> </div> </Route> <Route path="/detail"> <Detail /> </Route> <Route path="/:id"> <div>아무거나 적으면 이거보여줌</div> </Route>
이렇게 경로가 / , /detail , /:id( /:id는 /뒤에 아무문자나 오면 여기로 보내라 라는 뜻 ) 세개일 때, /detail에 들어가면
path="/:id"의 라우터가 보여진다. 이것을 방지하기 위해 switch 컴포넌트를 사용한다. 여러개가 맞아도 하나만 보여주세요 라는 뜻이고
<Switch> <Route exact path="/"> //html덩어리 </Route> <Route path="/detail"> <Detail /> </Route> <Route path="/:id"> <div>아무거나 적으면 이거보여줌</div> </Route> </Switch>
이런 식으로, Route들을 감싸준다. 즉, 중복매칭을 허용하지 않는다. 이러면 exact를 쓰지 않고도 해결가능하다.
순서를 바꿔주면 되는데, /detail처럼 /뒤에 더 주소가 있는것을 상단에 놓고, 다음에 /:id 그리고 마지막에 /를 놓으면 exact를 쓰지 않아도 잘 작동한다.
'React' 카테고리의 다른 글
styled-components (0) 2022.03.17 여러 페이지 만들기 router활용 (0) 2022.03.16 Router의 기본 (0) 2022.03.15 import / export (0) 2022.03.14 React의 bootstrap과 img관리 (0) 2022.03.14