TIL(Today I Learned)/스파르타 내배캠
[TIL] 23/12/06 React 심화: 아웃소싱 프로젝트 (React Query 마스터하기)
개발자먼지
2023. 12. 6. 23:57
반응형
강의듣고, 튜터님 질문하고, 동기 질문하고
마스터 해버림
정리는 못함. 그래서 코드를 첨부하고 주석을 달았다.
TIL
Naver 지역 검색 api 와 함께하는 React Query
내 component : MapSearch.jsx
function MapSearch() {
const [inputTitle, setInputTitle] = useState('');
const [localList, setLocalList] = useState([]);
// enabled 사용 : false로 두었다가 검색버튼 클릭 시 refatch해서 data 불러옴
// select 사용 : data에 원래 받아온 데이터에서 items 객체만 선택해서 가져옴
// isLoading, isError 상태를 유저에게 보여주기 위해 받아옴
const { isLoading, isError, refetch, data } = useQuery(
['local', { local: inputTitle }],
getLocal,
{ enabled: false, select: (local) => local.items }
);
// 검색 버튼 핸들러에서 refetch
// localList에 저장한 것은 나중에 redux 전역 상태 관리로 변경 예정
// list 형태의 data 여서... 풀어서 다시 [] 배열에 저장했음, 애초에 왜 []형태로 잡았는가..
const searchPlaceHandler = async (e) => {
e.preventDefault();
const { data } = await refetch();
console.log('clicked', data);
setLocalList(...data);
};
// input 이벤트 핸들러, 입력값을 저장
const inputTitleHandler = (e) => {
setInputTitle(e.target.value);
};
return (
<StyledMap>
<form onSubmit={searchPlaceHandler}>
<input
type="text"
placeholder="장소를 입력해주세요"
value={inputTitle}
onChange={inputTitleHandler}
/>
<button type="submit">검색</button>
</form>
<StListArea>
{isLoading && <h1>로딩중입니다...!</h1>}
{isError && <h1>오류가 발생하였습니다..!</h1>}
{data ? (
data.map((item, index) => {
return (
<StArea key={index}>
<p>{item.title}</p>
<p>{item.address}</p>
</StArea>
);
})
) : (
<p>검색을 해주세요</p>
)}
</StListArea>
</StyledMap>
);
}
react query api : local.js
import axios from 'axios';
//주소에는 proxy로 설정해준 주소 뒷부분을 적어주어야 한다.
//component에서 queryKey로 넘겨준 입력값을 첫번째 매개변수에서 찾아서 쿼리로보냈다.
//쿼리에는 결국 검색어가 들어간다.
// 네이버 api를 사용하기위한 key 값 헤더로 넘겨주어야 한다(.env파일에 저장해두었음)
const getLocal = async (input) => {
const { data } = await axios.get('/v1/search/local.json', {
params: {
query: input.queryKey[1].local,
display: 5
},
headers: {
'X-Naver-Client-Id': process.env.REACT_APP_LOCAL_CLIENT_ID,
'X-Naver-Client-Secret': process.env.REACT_APP_LOCAL_CLIENT_SECRET
}
});
return data;
};
export { getLocal };
app.js
import { QueryClient, QueryClientProvider } from 'react-query';
import Router from 'shared/Router';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Infinity //TODO : 서버 접근횟수 때문에 임시로 1회만 호출되도록 했다
}
}
});
function App() {
return (
<QueryClientProvider client={queryClient}>
<Router />
</QueryClientProvider>
);
}
export default App;
package.json
"proxy": "https://openapi.naver.com", //를 추가해준다. CORS 에러 방지
완성 화면
동영상은 어떻게 찍는지 모르겠고,
css는 아직 안꾸몄고,
data로 넘어온 title을 그대로 찍었더니 검색어에 <b> </b> 가 붙어져 나온다. 후후
반응형