이번에는 기능 구현의 거의 마지막 파트였던 검색 기능과 검색 페이지를 구현했다. 미리보기 기능은 검색 페이지 설정에서 새창으로 검색 화면을 볼 수 있는 기능이기 때문에 검색 페이지가 구현되면 컴포넌트를 복사해 이벤트를 없애서 구현하였다.
검색 기능은 검색 창에 단어를 입력해서 엔터나 검색 버튼을 누르면 검색 페이지로 이동하면서 해당 단어의 데이터를 가져오는 부분이기 때문에 클라이언트에 url에 단어가 포함되도록 해야한다. 단어를 state나 redux로 관리하게 되면 페이지가 새로고침 되면 데이터가 초기화되기 때문에 다른 포털 사이트 처럼 url에 포함하는 방식을 사용하였다.
function App() { ... return ( <div className='App'> <div className='App-content'> <Switch> ... <Route path='/search/query=:word' component={Search} /> <Route path='/search/query=' component={Search} /> ... </div> </div> ); }
export default function Search({ match }) { const { word } = match.params; ... const getSearchData = useCallback(async () => { const res = await axios.get( `${process.env.REACT_APP_SERVER_API}/search/word`, { params: { word }, withCredentials: true, } ); if (res.data.id) { setSearchData([ res.data.profile, res.data.news, res.data.image, res.data.music, ]); } }, [setSearchData, word]); ... useEffect(() => { getSearchData(); }, [getSearchData]); ... return ( <div className='search-container'> ... <div/> ); }
이전에 다가치 프로젝트나 쉘위헬스에서 게시물 페이지에서 적용한 방법대로 path에 :
을 붙이고 변수명을 설정하면 해당 컴포넌트에서 match.params
로 받아올 수 있는데 그때와는 다르게 검색어가 빈 문자열인 경우도 설정을 해주어야했다. 처음에는 서버에 요청을 보낼때 검색어가 없어서 에러가 나는 것이라고 판단해서 match.params.word
가 undefined
인 경우를 분리해서 서버에 요청을 보내주었는데 알고보니 애초에 path를 '/search/query=:word'
로 설정해주었기 때문에 단어가 없는 경우에 해당 컴포넌트로 연결이 안되는 것이 문제였다. <Route path='/search/query=' component={Search} />
이렇게 단어가 없는 경우에도 Search 컴포넌트로 이동할 수 있도록 라우트 설정을 추가해주었다.
검색 페이지는 해당 유저가 설정한 검색어에 해당하는 데이터를 서버에서 받아서 보여주는 기능으로 어려운 로직은 없어서 쉽게 구현하였다. 각 섹션의 구조대로 map을 적절하게 사용해서 보여질 수 있도록 설정하였다.
export default function Image({ imageData }) { return ( <div className='image-container'> ... {imageData.img1 !== '' ? ( <img src={imageData.img1} alt='images' className='images' onError={(e) => { e.target.onerror = null; e.target.src = '../../img/no-image-row.png'; }} /> ) : ( <div className='images'> 설정된 이미지가 <br /> 존재하지 않습니다. </div> )} ... </div> ); }
유저가 이미지를 설정하지 않아서 src가 빈 문자열인 경우에 보여질 박스와 혹시나 서버 문제로 이미지가 다운로드 되지 않았을때 보여질 대체 이미지를 onError 속성을 이용해 설정해주었다.
미리보기 기능은 검색 페이지를 구현한 후 해당 컴포넌트를 복사해서 onClick과 같은 이벤트들을 없애서 클릭 시에도 작동하지 않도록 설정해주었다.
이번 프로젝트를 하면서 느낀 점은 검색 기능을 구현하려면 데이터를 가져오고 보여줘야 하는 부분, 유저가 검색어를 입력하고 검색 페이지를 접하는 과정에서 개발자로서 고려해야하는 부분이 많다는 것을 알았다. 실제 서비스를 구현하기 위해서는 단순히 기능 구현뿐만 아니라 실제 유저의 입장이 되어서 생각하는 것이 중요하다고 느꼈다.