카테고리 없음

React 'react-query' 사용기

seongjin08 2022. 5. 5. 15:54

$  npx create-react-app [파일명]

으로 react 프로젝트를 생성한다.

 

src 폴더 안에 app.js , index.js , index.css 파일 빼고 삭제 해준다.

src 폴더 안에 components 폴더를 만들고 Navbar.js,People.js ,Planets.js 파일을 생성해 준다.

 

app.js 

import React,{useState} from "react";
import Navbar from "./components/Navbar";
import Planets from "./components/Planets"
import People from "./components/People"

function App() {
  const [page, setPage] = useState('planets')
  return (

    <div className="App">
      <h1> useQuery test</h1>
      <Navbar setPage={setPage} />
      <div className="content">
        {page === 'planets' ? <Planets /> : <People />}

      </div>
    </div>

  );
}

export default App;

index.css

body {
  margin: 0;
  font-family: sans-serif;
  background: #222;
  color: #ddd;
  text-align: center;
}
.App{
  width: 960px;
  margin: 0 auto;
}
h1{
  color: #ffff57;
  font-size: 4em;
  letter-spacing: 2px;
}
button{
  margin: 0 10px;
  background: transparent;
  border: 3px solid #ccc;
  border-radius: 20px;
  padding: 10px;
  color: #ccc;
  font-size: 1.2em;
  cursor: pointer;
}
button:hover{
  color: #fff;
  border-color: #fff;;
}
.content{
  text-align: left;
}

index.js

import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Navbar.js

import React from "react"

const Navbar = ({setPage}) =>{
return(
  <nav>
      <button onClick={()=>setPage('planets')} >Planets</button>
      <button onClick={()=>setPage('people')}>People</button>
  </nav>
)}

export default Navbar;

People.js

import React from 'react';

const People = () =>{
return(
    <div>
        <h2>People</h2>
    </div>
)
}


export default People;

Planets.js

import React from 'react';

const Planets = () => {
    return (
        <div>
            <h2>Planets</h2>
        </div>
    )
}

export default Planets;

$  npm start

이렇게 코드 작성을 이렇게 나올것이다. 이제 부터 usequery 를 사용하여 작업을 해볼 것이다. 

$  npm install --sava react-query

Planets.js

import React from 'react';
import { useQuery } from 'react-query';

const fetchPlanets = async () => {
    const res = await fetch('http://swapi.dev/api/planets/')
   console.log(res);
    return res.json();
}

const Planets = () => {
    const { data } = useQuery('test', fetchPlanets);
                             // 첫번째 인자값으로 스트링으로 이름을 넣어준다.
                             // 두번째 인자값은 여기서 사용할 비동기 함수를 넣어준다.
    console.log(data);
    return (
        <div>
            <h2>Planets</h2>
        </div>
    )
}


export default Planets;

 

이렇게 작성 하고 브라우져를 보면 이런 에러가 나올 것이다.

QueryClient 의 셋팅이 안되어 있다는 에러이다. 이 에러를 해결하기 위해서는 App.js 파일에서 셋팅을 해주어야 한다.

App.js

import React, { useState } from "react";
import Navbar from "./components/Navbar";
import Planets from "./components/Planets"
import People from "./components/People"
import { QueryClient, QueryClientProvider } from 'react-query'

const queryClient = new QueryClient()

function App() {
  const [page, setPage] = useState('planets')
  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1> useQuery test</h1>
        <Navbar setPage={setPage} />
        <div className="content">
          {page === 'planets' ? <Planets /> : <People />}

        </div>
      </div>
    </QueryClientProvider>

  );
}

export default App;

이렇게 QueryClient 셋팅을 해주면 에러를 해결 할 수 있다.

 

Planets.js

import React from 'react';
import { useQuery } from 'react-query';

const fetchPlanets = async () => {
    const res = await fetch('http://swapi.dev/api/planets/')
    console.log(res);
    return res.json();
}

const Planets = () => {
    const { data, status } = useQuery('test', fetchPlanets);
    console.log(data);
    return (
        <div>
            <h2>Planets</h2>
            // status 로 비동기 함수의 상태를 확인 할 수 있다.
            {status === 'loading'&&(
                <div>Loading data...</div>
            )}
            {status === 'error'&&(
                <div>Error fetching data</div>
            )}
            {status === 'success'&&(
                // <div>success fetching data</div>
                <div>
                    {data.results.map(Planets => <div>{Planets.name}</div>)}
                </div>
            )}
        </div>
    )
}


export default Planets;

브라우져에서 이렇게 정보를 가져 오는 것을 확인 할 수 있다.

component 폴더안에 planet.js  파일을 생성하고 코드를 작성해 준다.

Planet.js

import React from 'react';

const Planet = ({ planet }) => {
    return (
        <div className="card">
            <h3>{planet.name}</h3>
            <p>Population - {planet.population}</p>
            <p>Terrain - {planet.terrain}</p>
        </div>
    )
}

export default Planet;

Planets.js    (success 일때 코드를 이렇게 수정해 준다. 성공시 정보를 props 로 넘겨준다.)

{status === 'success'&&(
                // <div>success fetching data</div>
                <div>
                    {data.results.map(planet => <Planet key={planet.name} planet={planet} />)}
                </div>
            )}

index.css. ( 추가)

.card{
  padding: 8px 16px;
  background: #1b1b1b;
  margin: 16px 0;
  border-radius: 20px;
}
.card p{
  margin: 6px 0;
  color: #999;
}
.card h3{
  margin: 10px 0;
  color: #ffff57;
}

이렇게 만들어 진다. 

People.js 는 위와 같은 방법으로 수정하여 비동기로 호출 url 만 바꾸어 주면  행성 정보와 사람 정보를 가져 올 수 있다.

 const res = await fetch('http://swapi.dev/api/people/')

People.js

import React from 'react';
import { useQuery } from 'react-query';
import Person from './Person';
const fetchPlanets = async () => {
    const res = await fetch('http://swapi.dev/api/people/')
    console.log(res);
    return res.json();
}

const People = () => {
    const { data, status } = useQuery('People', fetchPlanets);
    console.log(data);
    return (
        <div>
            <h2>People</h2>

            {status === 'loading'&&(
                <div>Loading data...</div>
            )}
            {status === 'error'&&(
                <div>Error fetching data</div>
            )}
            {status === 'success'&&(
                // <div>success fetching data</div>
                <div>
                    {data.results.map(person => <Person key={person.name} person={person} />)}
                </div>
            )}
        </div>
    )
}

export default People;

 

Person.js

import React from 'react';

const Person = ({ person }) => {
    return (
        <div className="card">
            <h3>{person.name}</h3>
            <p>Population - {person.gender}</p>
            <p>Terrain - {person.birth_year}</p>
        </div>
    )
}

export default Person;