--
프로젝트 구조를 잡고 메인 화면에 "Hello World"까지 출력해 보았습니다. 이제 화면의 제목과 검색 기능을 담당하는 Header 영역을 만들어보겠습니다.
Header나 Footer 등 독립적인 기능을 담당하는 요소를 Component라고 부릅니다. 우리도 프로젝트에 /src/components 디렉토리를 하나 생성합니다.
그 다음 Header는 Layout 중 일부이므로 /src/components/layout/ 아래 생성하여 관리하도록 하겠습니다. /src/components/layout/Header.jsx 파일을 하나 생성합니다.
이전 게시글에서 보았던 Header의 모양 및 기능을 상기해 봅니다. 정의했던 요건은 아래와 같습니다.
최초
화면 제목과 돋보기 버튼이 표시됩니다. 돋보기 버튼을 선택하면 화면 제목 영역이 검색어를 입력할 수 있는 입력 상자로 변경됩니다.
검색어 입력 후 돋보기 버튼 터치
검색어를 입력한 후 돋보기 버튼을 터치하면 입력한 검색어로 NAVER API를 검색합니다.
검색 후
Header는 다시 "NAVER API 연계"라는 텍스트로 변경됩니다.
일단 최초 요건부터 만들어 보겠습니다. Header.jsx를 아래와 같이 코딩합니다.
import React from 'react';
const Header = (props) => {
return (
<header className="header">
<div>
<h1>NAVER API 연계</h1>
</div>
<button type="button" className="icoBtn search">
<span>검색</span>
</button>
</header>
);
};
export default Header;
header 태그 하위에 텍스트를 표시하는 영역과 버튼을 생성합니다. 아직 버튼의 동작은 구현하지 않았습니다. 아직 props를 전달 받을지 말지 확정되지 않았으나 추후 받을지도 모르니 일단 코드에 포함시키겠습니다.
위 태그에 대응하는 css는 아래와 같이 추가합니다. main.css 하단에 추가하면 됩니다.
.icoBtn{border:none;outline:none;display:inline-block;background-color:transparent;background-repeat:no-repeat;background-size:cover;background-position:0 0;vertical-align:middle;}
.icoBtn span{clip-path:inset(50%);}
.icoBtn.search{width:49px;height:49px;background-image:url(../image/icoSearch.png);}
header {position:fixed;top:0;left:0;width:100%; height:50px;background-color:#FFF;border-bottom:1px solid #DDD;}
header h1 {font-size:1.8rem;line-height:49px;text-align:center;margin:0;}
header .icoBtn.search{position:absolute;right:0px;left:auto;top:0;border-left:1px solid #DDD;}
간단히 모양과 위치 정도만 잡아줍니다.
작업한 결과물을 보기 위해 http://localhost:8080 으로 들어가면 아직 "Hello World"만 표시됩니다. 화면에 표시하는 영역의 내용을 변경하기 위해 main.js를 아래와 같이 수정하도록 하겠습니다.
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './components/layout/Header.jsx';
ReactDOM.render(<Header />, document.getElementById('app'));
위와 같이 수정한 후 다시 실행하면 아래와 같은 오류가 발생합니다.
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/a20201022/Documents/searchNaverApi/src/main.js: Support for the experimental syntax 'jsx' isn't currently enabled (5:17):
3 | import Header from './components/layout/Header';
4 |
> 5 | ReactDOM.render(<Header />, document.getElementById('app'));
JSX 문법은 브라우저가 바로 해석할 수 있는 형태가 아니라 babel을 통해 compile을 해야 브라우저가 해석할 수 있는 형태가 되지만 우리는 아직 babel 설정을 하지 않았습니다.
프로젝트 root에 .babelrc 라는 파일을 하나 생성하고 아래와 같이 코딩합니다.
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
위의 작업까지 마치고 다시 실행해보면 화면이 표시되지만 돋보기 버튼은 표시되지 않습니다. 아래 이미지를 다운로드하여 /public/image/icoSearch.png 로 저장합니다.
그러면 화면이 아래와 같이 표시됩니다.
현재까지 작성한 프로젝트 구조는 아래와 같습니다.
state를 사용하여 돋보기 버튼 클릭에 따라 상태를 변경해 보도록 하겠습니다. 처음에는 Header 영역에 "NAVER API 연계" 텍스트를 표시하고, 돋보기 버튼을 한 번 클릭하면 Header 영역을 inputbox로 변경하겠습니다.
다시 한 번 더 돋보기 버튼을 클릭하면 다시 "NAVER API 연계" 텍스트가 표시되도록 변경해 보겠습니다. Hook을 사용하여 개발하겠습니다.
Header.jsx 파일을 열어 아래 내용들을 수정해 보겠습니다.
import React, { useState } from 'react';
const [showInput, setShowInput] = useState(false);
const clickBtnSearch = () => {
setShowInput(!showInput);
};
{
showInput ?
<input type="text" className="iptSearch" id="iptSearch" /> :
<h1>NAVER API 연계</h1>
}
<button type="button" className="icoBtn search" onClick={clickBtnSearch}>
<span>검색</span>
</button>
위 내용을 모두 수정한 Header.jsx 파일은 아래와 같습니다.
import React, { useState } from 'react';
const Header = (props) => {
const [showInput, setShowInput] = useState(false);
const clickBtnSearch = () => {
setShowInput(!showInput);
};
return (
<header className="header">
<div>
{
showInput ?
<input type="text" className="iptSearch" id="iptSearch" /> :
<h1>NAVER API 연계</h1>
}
</div>
<button type="button" className="icoBtn search" onClick={clickBtnSearch}>
<span>검색</span>
</button>
</header>
);
};
export default Header;
inputbox를 위한 css를 main.css에 살짝 추가합니다.
.iptSearch{width:calc(100% - 90px);border:0;line-height:49px;outline:1px solid #DDD;padding:0px 70px 0px 20px;}
여기까지 코딩을 하고 돋보기 버튼을 클릭하면 텍스트와 inputbox가 toggle 되면서 표시됩니다.
실제 검색을 하기 위해서는 API와 연결해야 하므로 그 작업은 ListView 까지 만들어 본 후에 다시 진행해 보겠습니다.
수고하셨습니다.