An amazing request tool which perfectly compatible with React, quick tutorial is HERE
Tags: javascript, react, alova, axios
Published: 2023-12-01 10:07:55

alova is a lightweight request strategy library designed to simplify the management and use of interfaces. By simply configuring parameters, you can implement complex requests such as sharing requests, paging requests, form submissions, breakpoint resumption, etc., without writing a lot of code, improving development efficiency, application performance, and reducing server pressure.

After using alovajs, you only need to select the corresponding useHook to make a request. alova also supports the `vue/react/svelte` framework. If you also like alovajs, please contribute a star in [Github repository](https://github.com/alovajs/alova), which is very important to us.

This article serves as a basic introduction to react+alova. You can learn the following:

1. How alova handles frequent requests and fuzzy searches gracefully
2. How alova helps manage server status under react projects
3. Smooth use of alova

## Welcome to join the communication community

If you have any usage questions, you can join the following group chat for consultation, or you can publish Discussions in [github repository](https://github.com/alovajs/alova/discussions). If you encounter problems, please also post in [github's issues](https://github.com/alovajs/alova/issues), we will solve it as soon as possible.

* [Join the Discord community to participate in communication](https://discord.gg/S47QGJgkVb)

You are also welcome to contribute, please go to [Contribution Guide](https://alova.js.org/contributing/overview).

## Install alova

```bash
npm install alova --save-dev
```

## Initialize an alova instance

In the following introductory guide, we will use to-dos as an example to explain the needs of obtaining to-do lists for different dates, viewing todo details, and creating, editing, and deleting items!

An `alova` instance is the starting point from which all requests start. It is written similarly to `axios`. The following is the simplest way to create an `alova` instance.

```javascript
import { createAlova } from 'alova';
import GlobalFetch from 'alova/GlobalFetch';
import ReactHook from 'alova/react';
const alovaInstance = createAlova({
   // Suppose we need to interact with the server of this domain name
   baseURL: 'https://api.todo.com',

   // ReactHook is used to create ref status, including request status loading, response data data, request error object error, etc.
   statesHook: ReactHook,

   //Request adapter, here we use fetch request adapter
   requestAdapter: GlobalFetch(),
  
   //Set a global request interceptor, similar to axios
   beforeRequest(config) {
     // Suppose we need to add token to the request header
     config.headers.token = 'token';
   },

   //Response interceptor, also similar to axios
   async responded(response, config) => {
     const json = await response.json();
     if (json.code !== 200) {
       // When an error is thrown here, it will enter the request failure interceptor.
       throw new Error(json.message);
     }
     return json.data;
   },
});
```

## todo list - directly use the state managed by `alova` for interface rendering

Our interface in this demo looks like this.

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7b00976f92a64d0396e83c09d813ea95~tplv-k3u1fbpfcp-watermark.image#?w=279\&h=408\&s=20261\ &e=png\&b=fbf9ff)

We use `useRequest` to send the request, which is the most commonly used method when the page obtains initialization data.

```jsx
const todoListGetter = alovaInstance.Get('/todo/list');
export const TodoList = () => {
     const {
     //Loading is the loading status value. When loading, its value is true, and it is automatically updated to false after the end.
     // It is a Ref type value, you can access it through loading.value, or bind it directly to the interface
     loading,

     // response data
     data: todoList,

     //Request error object, it has a value when requesting an error, otherwise it is undefined
     error,

     //Successful callback binding
     onSuccess,

     // Failure callback binding
     onError,

     //Complete callback binding
     onComplete,

     // Directly pass in the Method object to send the request
   } = useRequest(todoListGetter, {
     //Initial data data
     initialData: [],
   });

   // ###### Callback settings
   onSuccess(todoListRaw => {
     console.log('The request was successful, the response data is:', todoListRaw);
   });
   onError(error => {
     console.log('The request failed, the error message is:', error);
   });
   onComplete(() => {
     console.log('The request is completed, it will be called regardless of success or failure');
   });
  
   if (loading) {
     return <div>Loading...</div>;
   }
   if (error) {
     return <div class="error">{ error.message }</div>;
   }
   return todoList.map(todo => {
     return (
       <div class="todo">
         <div class="todo-title">{{ todo.title }}</div>
         <div class="todo-time">
             <span class="time">{{ todo.startTime }}</span>
             to
             <span class="time">{{ todo.endTime }}</span>
         </div>
       </div>
     );
   });
}
```

### Todo list page - changed to fuzzy search for todo items

The fuzzy search function is to continuously issue requests during the process of entering keywords. At this time, we replace the above useRequest with useWatcher to automatically re-obtain data when the keyword changes.

> In order to improve the user experience and reduce the pressure on the server, we have also implemented search anti-shake.

The implementation code is as follows:

```jsx
export const TodoList = () => {
   // ...omit duplicate code

   const searchTodo = keyword => alovaInstance.Get(`/todo/list?keyword=${keyword}`);

   // Replace useRequest with useWatcher
   // Monitor keyword changes through useWatcher, and automatically reissue the request after the change
   const [keyword, setKeyword] = useState('');
   const {
     loading,
     error,
     data,
   } = useWatcher(() => searchTodo(keyword), [keyword], {
     debounce: 500, // Set 500 milliseconds request-level anti-shake, no need to implement anti-shake function yourself
   });

   return // ...view code is the same as above
};
```

In this way, the fuzzy search function with anti-shake is realized.

## todo editing page - cache frequently requested data in memory

The edit page looks like this:

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c400d3a9d14e475aa3cc0d057d217099~tplv-k3u1fbpfcp-watermark.image#?w=302\&h=519\&s=23320\ &e=png\&b=ffffff)

### Get the edit page data and echo it

Our scenario needs to be considered here. The user clicks on a todo item multiple times within a few seconds to view it. It is a bit wasteful to request the server every time he enters. At this time, we can do a layer of front-end caching to increase the display speed and reduce the pressure on the server. .

```jsx
const todoDetail = id => alovaInstance.Get(`/todo/${id}`, {
     //Set a local memory cache for 5 minutes, which will become invalid upon refreshing.
     localeCache: 5 * 60 * 1000,
});
export const TodoDetail => ({ id }) => {
   const {
     loading,

     // response data
     data: todoDetail,
     update
   } = useRequest(todoDetail(params.id));

   const handleAddTodo = () => {
     // Continue reading below
   }

   if (loading) {
     return <div>Loading...</div>;
   }
   return (
     <div>
       <input value={todoDetail.title} onInput={e => update({
         data: {
          ...todoDetail,
           title: e.target.value,
         }
       })} />
       <input value={todoDetail.date} onInput={e => update({
         data: {
         ...todoDetail,
           date: e.target.value,
         }
       })} />
       <input value={todoDetail.startTime} onInput={e => update({
         data: {
         ...todoDetail,
           startTime: e.target.value,
         }
       })} />
       <input value={todoDetail.endTime} onInput={e => update({
         data: {
         ...todoDetail,
           endTime: e.target.value,
         }
       })} />
       {/* ... */}
       <button onClick={handleAddTodo}>Submit data</button>
     </div>
   )
}
```

### Data submission code - manually update todo list data

Next, let's take a look at the operation of submitting data. We hope that it will directly update the data of the todo list across components after the submission is successful, instead of requesting data again to refresh the interface.

```jsx

export const TodoDetail = ({ id }) => {
   // ...
   // First create a new request to submit data, and set immediate to false so that the request will not be sent during initialization.
   const createTodoPoster = newTodo => alova.Post('/todo', newTodo);
   const {
     loading: submitting,
     data,
     error,

     // Manual sender request function, send the request after calling
     send: submitTodo,
   } = useRequest(() => createTodoPoster(todoDetail), {
     // When immediate is false, no request will be issued during initialization
     immediate: false
   });

   // Trigger submission request
   const handleAddTodo = () => {
     submitTodo()
       .then(result => {
         //Update the list data, get the todo list status, and return the updated data
         updateState(todoDetail(params.id), todoListData => {
             const index = todoListData.findIndex(({ id }) => id === params.id);
             todoListData[index] = todoDetail.value;
             return todoListData;
         });
       })
       .catch(error => {
         console.log('Failed to add todo item, error message is:', error);
       });
   };

   return (
     <div>
       {/*... */}
       <button loading={submiting} onClick={handleAddTodo}>Submit data</button>
     </div>
   )
}
```

# End

Now, you can also use alova in the options writing method of vue2, [click to view details](https://alova.js.org/tutorial/framework/vue-options)

[There are many runnable examples here](https://alova.js.org/category/examples)

If you think the article is helpful to you, please don't be stingy with your likes and comments. Tell me what you think of alovajs, or ask some questions. I will try my best to answer them. Your support is the biggest motivation for my creation! Hahahahahaha\~

If you want to learn more about the usage of alovajs, welcome to [alova official website](https://alova.js.org/) to learn. If you also like alovajs, please contribute a star in [Github repository](https://github.com/alovajs/alova), which is very important to us.

### Welcome to join the communication community

If you have any questions, you can join the following group chat for consultation, or you can publish Discussions in [github repository](https://github.com/alovajs/alova/discussions). If you encounter problems, please also post in [github issues ](https://github.com/alovajs/alova/issues) and we will solve it as soon as possible.

* [Join the Discord community to participate in communication](https://discord.gg/S47QGJgkVb)

At the same time, you are welcome to contribute, please go to [Contribution Area](https://alova.js.org/contributing/overview).