React Query 시작하기 - React에서 손쉬운 서버 상태 관리

22759 단어 reactstatewebdevredux

시작하기



서버에서 오는 상태 처리는 React에서 실제로 두통을 유발할 수 있습니다. 업데이트, 캐싱 또는 다시 가져오기와 같은 비동기 데이터를 처리할 때 생각해야 할 것이 많습니다.

이것이 react-query이 들어오는 곳입니다. 이를 원활하게 처리하고 낙관적 렌더링, 무한 스크롤, 페이지 매김 등을 위한 간단한 솔루션도 제공합니다.

다음은 우리가 구축할 작은 데모입니다.



코드로 바로 이동하려면 여기에서 리포지토리를 찾을 수 있습니다.
https://github.com/wwebdev/react-query-demo

이 자습서에서는 노드가 설치되어 있다고 가정합니다. 먼저 npx create-react-app 로 새 반응 앱을 만듭니다. 그런 다음 npm i --save react-query로 react-query를 설치합니다.

react-query 작동 방식을 보여주기 위해 Json Placeholder API을 사용하여 간단한 블로그를 만들겠습니다.

데이터 가져오기



우선 App.js에서 모든 상용구 코드를 제거하고 다음 코드로 대체하겠습니다.

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

const getPosts = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts')
  return response.json()
}

function App() {
  const { status, data, isFetching, error } = useQuery('posts', getPosts)

  if (status === 'loading') {
    return <div>loading...</div> // loading state
  }

  if (status === 'error') {
    return <div>{error.message}</div> // error state
  }

  return (
    <div>
      { data && <ul>{
        data
          .slice(0,10) // only take frist 10 for now
          // render list of titles
          .map(d => <li key={`post-${d.id}`}>{d.title}</li>)
      }</ul> }
      { isFetching && <p>updating...</p> }
    </div>
  )
}

export default App

먼저 getPosts라는 함수를 정의합니다. 이것은 비동기 함수를 반환하는 한 모든 것을 포함할 수 있습니다.
App() 시작 부분에서 가져오는 데이터의 식별자와 비동기 함수 getPosts를 사용하여 useQuery 후크가 호출됩니다.

후크는 상태, 데이터, isFetching 및 오류를 반환합니다. 그것들은 꽤 자명합니다. 상태는 "성공", "로드 중"또는 "오류"일 수 있습니다. 구성 요소의 나머지 부분은 세 가지 가능한 상태에 대한 결과 표시를 처리합니다.

react-query의 내부는 이제 모든 캐싱 및 업데이트 논리를 처리합니다. 즉, 이 페이지를 방문할 때마다 이전에 데이터를 가져온 경우 표시된 데이터가 즉시 있고 서버 상태와 함께 항상 최신 상태임을 알 수 있습니다.

이것이 바로 react-query를 사용하기 위해 알아야 할 전부입니다. 그러나 이 예제를 확장하여 이 캐싱 및 업데이트가 실제로 수행되는 것을 확인하십시오!

애플리케이션 확장



먼저 App.js에서 새 구성 요소components/Home.js로 코드를 이동하겠습니다. 따라서 구성 요소의 이름을 바꾸고 게시물 목록에 NavLink도 추가하겠습니다.

import React from 'react'
import { NavLink } from 'react-router-dom'
import { useQuery } from 'react-query'

const getPosts = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts')
  await new Promise(r => setTimeout(r, 1000)) // wait a second
  return response.json()
};

function Home() {
  const { status, data, isFetching, error } = useQuery('posts', getPosts)

  if (status === 'loading') {
    return <div>loading...</div> // loading state
  }

  if (status === 'error') {
    return <div>{error.message}</div> // error state
  }

  return (
    <div>
      { data && <ul>{
        data
          .slice(0,10) // only take frist 10 for now
          .map(d => <li key={`post-${d.id}`}>
            <NavLink to={`/post/${d.id}`}>{d.title}</NavLink>
          </li>) // render list of titles
      }</ul> }
      { isFetching && <p>updating...</p> }
    </div>
  );
}

export default Home

이제 라우터를 App.js에 추가해 보겠습니다. 라우터는 Home.js의 경우 /로, 단일 게시물 페이지의 경우 /post/:id로의 경로를 허용합니다.

import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

import Home from './components/Home'
import Post from './components/Post'

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path = '/post/:id' render = {routerProps => <Post id={routerProps.match.params.id}/>} />
      </Switch>
    </Router>
  )
}

export default App

마지막으로 단일 게시물의 데이터를 표시하기 위한 새 구성 요소components/Post.js를 만듭니다. 코드 다음에 설명이 나옵니다.

import React from 'react'
import { NavLink } from 'react-router-dom'
import { useQuery } from 'react-query'

const Post = ({ id }) => {
  const getPost = async () => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
    const jsonResponse = await response.json()
    jsonResponse.title = `${jsonResponse.title} - ${Math.random().toString(36)}`

    await new Promise(r => setTimeout(r, 1000)) // wait a second
    return jsonResponse
  }

  const { status, data, isFetching } = useQuery(`post-${id}`, getPost)

  if (status === 'loading') {
    return <div>loading...</div> // loading state
  }

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
      { isFetching && <p>updating...</p> }
      <br />
      <NavLink to="/">Home</NavLink>
    </div>
  )
}

export default Post

따라서 여기의 useQuery는 Home.js의 것과 크게 다르지 않습니다. 식별자에 id를 추가하므로 각 게시물마다 자체 상태가 있습니다. 또한 getPost 함수에 1초 동안의 시간 초과를 추가하여 로딩 상태를 더 잘 볼 수 있도록 했습니다. 또한 다시 가져오기를 볼 수 있도록 제목에 임의의 문자열을 추가했습니다.

그리고 그것은 실제로 게시물의 시작 부분에서 본 gif의 전체 코드입니다.

반응 쿼리 작업을 시작하는 경우 상태 및 캐시를 볼 수 있도록 react-query-devtools 을 확인하는 것이 좋습니다.

GitHub에서 코드를 확인하십시오. 또한 initial data , pre-fetching , optimistic rendering 와 같은 것에 대한 react-query 사용법에 대해 더 알고 싶다면 알려주세요. 이것을 일련의 게시물로 확장하겠습니다.

좋은 웹페이지 즐겨찾기