source: https://github.com/ziponia/react-kakao-search-api
지난 포스트 에 이어 이번엔 React router 를 사용 해 보도록 하자.
현재 서비스에는 문제점이 있다.
현재 페이지 어떤 URL 로 접속 하든간에 결과물을 볼 수 없다.
예를들어, A 가 “아메리카노” 라는 키워드를 검색하고, 그 결과물을 B에게 공유 하려고 URL 을 B 에게 보내도
B 는 그냥 빈 화면만 보게 될것이다.
이 문제를 해소하려면, 상태를 저장 해야하는데, 리액트에서 state 는 어떠한 환경에서든 (따로 구현을 하지 않는다면) 가장 초기에 설정 한 state 를 반환 할 수밖에 없는것이다.
그래서 이 부분은 react router 를 이용하여, 해소 해 보도록 하자.
먼저 react router 를 설치하자
$ yarn add react-router dom
다음으로, Route 처리를 할 컴포넌트를 만들자.
src/Client.js
import React from "react";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
const Client = props => {
return (
<BrowserRouter>
<App />
</BrowserRouter>
);
};
export default Client;
그 다음, index.js 를 가서 원래 App.js 를 랜더링 하던것을, Client 컴포넌트를 랜더링 하도록 변경하자.
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import Client from "./Client";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(<Client />, document.getElementById("root"));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
이제 경로에 따라서, 검색 쿼리를 변경 하도록 해줄것이다.
Client js 의 내용을 아래와 같이 변경 해주자.
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import App from "./App";
const Client = props => {
return (
<BrowserRouter>
<Switch>
<Route path="/search/:keyword" component={App} />
<Route exact path="/" component={App} />
</Switch>
</BrowserRouter>
);
};
export default Client;
- /search/:keyword 로 들어왔을 때 App 컴포넌트를 랜더링 한다.
- / 경로로 들어왔을때 App 컴포넌트를 랜더링 한다.
첫번째와 두번째의 차이점은, :keyword
가 있냐 없냐이다. 나중에 keyword
값을 컴포넌트 내부에서 받을 것이다.
app js 로 가서 App 컴포넌트를 withRouter 로 감싸준다.
src/App.js
// ...
import { withRouter } from "react-router-dom";
const App = props => {
// ...
// console.log(props);
};
export default withRouter(App);
App.js 안에서 콘솔을 보면 router props 들이 추가 된 것을 볼 수 있다.
App.js 상단에 아래와 같이 넣어주자.
App.js
const App = props => {
const { params } = props.match; // 1
const keyword = params.keyword || ""; // 2
// other..
};
1: route props 중 match 의 params 를 변수로 할당.
2: params 의 keyword 를 변수로 할당 및 빈 문자열로 초기화
이제 useEffect 함수의 query 를 keyword 로 변경 해주자.
const App = props => {
// ...
useEffect(() => {
if (keyword.length > 0) {
blogSearchHttpHandler(keyword, true);
} else {
setBlogs([]);
}
}, [keyword]);
//...
};
URL 에다가 쿼리를 넘겨보자
http://localhost:3000/search/짱구는못말려
이제 검색 필드의 default 값을 키워드로 변경 해 주자. query 는 필요없으니 지워준다.
const [text, setText] = useState("");
// to
const [text, setText] = useState(keyword);
// const [query, setQuery] = useState(keyword);
마지막으로, 엔터 이벤트가 발생 할때 url 을 교체 해 주는 작업을 해주면된다.
onEnter 함수를 다음과 같이 변경하자.
const App = props => {
//...
// 엔터를 눌렀을 때 호출 되는 함수
const onEnter = e => {
if (e.keyCode === 13) {
if (text.length === 0) props.history.push(`/`);
else props.history.push(`/search/${text}`);
}
};
//...
};
이제 새로고침을 해도, 상태가 유지 되는것을 볼 수 있다.
좀 더 코드에 대해 이해하고 싶다면,