preface
In the project, there is usually asynchronous data interaction with the server, basically using the axios library to do the request, well, after all, there is 80K star, star project
Next, let’s review the use of AXIos in the project
In the case of querying user information, we encapsulate it this way
async function requestUsers(){
const {data} =await axios.get('/api/users');
return data;
}
Copy the code
Use hooks to repackage this request, including loading and other intermediate states
import React, {useState,useEffect} from 'react';
import axios from 'axios';
function useUsersQuery(){
const [data,setData] = useState([]);
const [isLoading,setLoading] = useState(false);
const [isError,setError] = useState(false)
useEffect(() = >{(async()=>{
setLoading(true);
try{
const {data} = await axios.get('/api/users');
setData(data);
} catch((() = >{
setError(true);
})
setLoading(false);
})()
})
return {
data,
isLoading,
isError
};
}
function UserList(){
const {data, isLoading,isError} = useUsersQuery();
if (isLoading) {
return <div>loading</div>;
}
if (isError) {
return <div>error</div>;
}
return (
<div>
{
data.map((item)=>{
return <div>{item.name}</div>})}</div>)}Copy the code
As can be seen, requests are basically encapsulated in this way in our project. We not only need to request data, but also deal with intermediate states such as loading and error. This kind of general intermediate state processing logic may be repeated many times in different components.
In addition, current front-end projects, especially single-page applications, will use Flux, Redux, Mobox and other state management libraries, and store the data shared between components in the state management library. These can be divided into two categories. One is the intermediate state of user interaction, such as isLoading,isClose, ModalVisible and so on, the other category is server state (data)
The way we generally deal with it is stored in the global state management without any difference. In order to accommodate asynchronous requests, the state management library has such asynchronous solutions as Redux-Saga and Redux-Action
In fact, for redux and other state management libraries, there is no concept of async itself, only mutation operation. In order to support async, asynchronous action operation was imposed by force. In fact, these asynchronous middleware transmitted dispatch through the callback of the last request. We will not only a pot of stew on the global state management, data written also makes the project more and more bloated (so that the latter to simplify the rematch, dva scheme), we had thought, server-side state should not be placed in the global state management, global state management should be designed to handle user interaction in the middle of the state
Now, React Query
React Query
React Query is often described as a data-fetching library that React lacks, but more broadly it makes fetching, caching, synchronizing, and updating server state in the React program very easy.
What problem was solved
The server status has the following characteristics:
-
It is stored on a remote device and cannot be directly controlled locally
-
Asynchronous apis are required for querying and updating
-
Data may be unknowingly changed by another requester, causing data to be out of sync
Existing state management libraries (such as Mobx, Redux, etc.) are suitable for managing client state, but they don’t care how clients asynchronously request remote data, so they are not suited for handling asynchronous, service-side state.
React Query is designed to address these server state issues, and it also provides the following features:
-
Easier control of caching
-
Simplify multiple requests for the same data into one
-
Update expired data in the background
-
Know when data is “out of date”
-
Respond to changes in data as quickly as possible
-
Request performance optimization such as paging queries and lazy loading
-
Manages memory and garbage collection for server state
-
Query results are cached through structural sharing
Request intermediate processing
function Todos() {
const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
if (isLoading) {
return <span>Loading...</span>
}
if (isError) {
return <span>Error: {error.message}</span>
}
// also status === 'success', but "else" logic works, too
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>)}Copy the code
React Query automatically handles isLoading and isError requests properly. Don’t write repetitive logic in Suspense. Suspense also supports good handling of loading scenarios, especially partial loading.
State management for ReactQuery
Fetch, cache and update data in your React and React Native applications all without touching any “global state”.
React Query is a request library that manages the state of the data. React Query is a request library that manages the state of the data
This is because ReactQuery globally maintains a server state tree, looks for available data in the state tree based on the Query key, returns the data if there is any, and otherwise initiates a request and stores the result of the request into the state tree with the Query key as the primary key.
ReactQuery maintains all of our server state globally and performs data storage and updates in conjunction with its caching strategy. With this feature, we can take all data interacting with the server out of a state management tool like Redux and hand it all over to ReactQuery.
Here’s an example:
import React from "react";
import { useQuery, queryCache } from "react-query";
import "./styles.css";
export default function App() {
return (
<div className="App">
<h1>Shared state using react-query</h1>
<Comp1 />
<Comp2 />
</div>
);
}
function useSharedState(key, initialValue) {
const { data: state } = useQuery(key, () = > queryCache.getQueryData(key), {
initialData: initialValue
});
const setState = value= > queryCache.setQueryData(key, value);
return [state, setState];
}
function Comp1() {
const [count, setCount] = useSharedState("count".1);
console.log("comp1 rendered");
return (
<div>
<p>Count: {count}</p>
<button onClick={()= > setCount(count + 1)}>add</button>
</div>
);
}
function Comp2() {
const [count, setCount] = useSharedState("count".2);
console.log("comp2 rendered");
return (
<div>
<p>Count: {count}</p>
<button onClick={()= > setCount(count + 1)}>add</button>
</div>
);
}
Copy the code
React Query state management can be implemented by the above method, but there are performance problems, in fact, the nature of the use of Context passthrough, we know that Context handles prop Drilling problems, but there are performance problems. React-5 Things That Might Surprise You
However, the official emphasis on ReactQuery state management is puzzling, but there is no similar example on the official github repository
The author said that he would analyze it in a lecture, and I would study it in depth later, leaving a hole first
reference
-
react-query.tanstack.com/quick-start
-
Github.com/tannerlinsl…
-
Github.com/tannerlinsl…
-
Tkdodo. Eu/blog/react -…