DEV Community

Cover image for useWatcher of alovajs, a request strategy library
Scott Hu
Scott Hu

Posted on

useWatcher of alovajs, a request strategy library

Alova is a lightweight request strategy library designed to simplify interface management and usage. It consists of 2 parts:

  1. Declarative implementation of complex requests: You can implement complex requests such as request sharing, pagination, form submission, breakpoint resume, etc. by simply configuring parameters without writing a lot of code, improving development efficiency and application performance and reduce pressure on the server.

  2. API automatic management and maintenance: You no longer need to define the request functions by yourself, and you no longer need to consult the API documentation. alova can help you generate a complete and detailed TypeScript type of the request function, so that the front-end project can be integrated with the server-side seamless. When the server-side API is updated, the front-end project will also be notified and the project will be blocked from publishing.

There are many runnable examples here

With Alova, all you need to do is select the appropriate useHook for your requests, now it support React, Vue, and Svelte. If you find alova helpful, please consider star on GitHub repository.

Join Our Community

If you have any questions or need assistance, you can join our communication or start a discussion on GitHub repository for support. If you encounter any issues, please submit them on GitHub issues, and we'll address them as soon as possible.

We also welcome contributions. For more information, please visit contribution guidelines.

For tutorials and more on how to use Alova, feel free to explore the alova documentation.

Request when states changed

In some scenarios that need to be re-requested as the data changes, such as paging, data filtering, and fuzzy search, useWatcher can be used to watch the specified state change and send the request immediately.

The following code is used React.

Keyword Search

Next, let's take searching for todo items as an example.

// create method instance
const filterTodoList = keyword => {
  return alovaInstance.Get('/todo/list/search', {
    params: {
      keywords
    }
  });
};

const App = () => {
  const [keyword, setKeyword] = useState('');
  const {
    loading,
    data,
    error
    // The first parameter must be a function that returns a method instance
  } = useWatcher(
    () => filterTodoList(keyword),

    // array of states being watched, these state changes will trigger a request
    [keyword],
    {
      // Set 500ms debounce, if the keyword changes frequently, only send the request 500ms after the change stops
      debounce: 500
    }
  );

  return (
    <>
      {/* keyword changes with input content */}
      <input
        value={keyword}
        onInput={e => setKeyword(e.target.value)}
      />

      {/* Render the filtered todo list */}
      {loading ? <div>Loading...</div> : null}
      {!loading ? (
        <>
          {data.map(todo => (
            <div>
              <div class="todo-title">{todo.title}</div>
              <div class="todo-time">{todo.time}</div>
            </div>
          ))}
        </>
      ) : null}
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

pagination

Using the todo list pagination request as an example, you can do this.

import { useState } from 'react';

// method instance creation function
const getTodoList = currentPage => {
  return alovaInstance.Get('/todo/list', {
    params: {
      currentPage,
      pageSize: 10
    }
  });
};

const App = () => {
  const [currentPage, setCurrentPage] = useState(1);
  const {
    loading,
    data,
    error

    // The first parameter is the function that returns the method instance, not the method instance itself
  } = useWatcher(
    () => getTodoList(currentPage),
    // array of states being watched, these state changes will trigger a request
    [currentPage],
    {
      // โš ๏ธCalling useWatcher does not trigger by default, pay attention to the difference with useRequest
      // Manually set immediate to true to initially obtain the first page data
      immediate: true
    }
  );

  return {
    /* ... */
  };
};
Enter fullscreen mode Exit fullscreen mode

Set initial response data

Before a page gets the initial data, it inevitably needs to wait for the response from the server. Before the response, it is generally necessary to initialize the state to an empty array or an empty object, so as not to cause an error on the page. We can set the second parameter to set the initial data.

// You can also set the initial value of data in useWatcher
const {
  // The initial value of data before the response is [], not undefined
  data
} = useWatcher(
  () => getTodoList(/* parameter */),
  [
    /* watch states */
  ],
  {
    initialData: []
  }
);
Enter fullscreen mode Exit fullscreen mode

Set the debounce time of all watching states

const { loading, data, error } = useWatcher(() => filterTodoList(keyword, date), [keyword, date], {
  // highlight-start
  // When debounce is set to a number, it represents the debounce time of all listening states, in milliseconds
  // As shown here, when one or more changes of states keyword and date, the request will be sent after 500ms
  debounce: 500
  // highlight-end
});
Enter fullscreen mode Exit fullscreen mode

Set debounce time for a single watching states

In many scenarios, we only need to stabilize some frequently changing watching states, such as state changes triggered by onInput of a text box, we can do this:

const { loading, data, error } = useWatcher(() => filterTodoList(keyword, date), [keyword, date], {
  // highlight-start
  // Set the debounce time respectively in the array order of the watching state, 0 or no transmission means no debounce
  // The order of the watching states here is [keyword, date], and the debounce array is set to [500, 0], which means that the debounce is only set for the keyword alone
  debounce: [500, 0]
  // You can also set it as follows:
  // debounce: [500],
  // highlight-end
});
Enter fullscreen mode Exit fullscreen mode

(End)Why Use Alova

Alova is committed to addressing client-side network request challenges, but what sets it apart from other request libraries is its focus on business-scenario-driven request strategies. When used in conjunction with libraries like axios/fetch api, Alova can meet 99% of your request needs while offering a range of advanced features.

  • You may have pondered over whether to encapsulate fetch and axios, but now you no longer need to. With Alova, you can use a declarative approach to fulfill complex requests, including request sharing, pagination, form submissions, and resumable uploads, as well as automated cache management, request sharing, and cross-component state updates.

  • Alova is lightweight, occupying only 4kb+, which is just over 30% of Axios's size.

  • It currently supports vue/react/react-native/svelte and SSR frameworks like next/nuxt/sveltekit, as well as cross-platform frameworks like Uniapp/Taro.

  • Alova is loosely coupled, allowing you to use it in any JavaScript environment with any UI framework using different adapters. It offers a unified user experience and seamless code migration.

  • Alova also promotes a highly organized approach for aggregating API code, grouping request parameters, cache behavior, and response data transformations in the same code blocks, which is advantageous for managing numerous APIs.

Compare Alova with other request libraries

Multi-Framework Support

Now, you can perfectly use Alova in vue options (vue2 and vue3) syntax. In the future, we plan to support the following frameworks:

  • Functional ones like solid/preact/qwik.
  • Class-based ones like angular/lit/stencil.
  • Options-based ones like native Chinese mini-programs.

Alova also offers powerful request strategies:

Name Description Documentation
Pagination request strategy Automatically manage paging data, data preloading, reduce unnecessary data refresh, improve fluency by 300%, and reduce coding difficulty by 50% usePagination
Non-sense data interaction strategy A new interactive experience, submission and response, greatly reducing the impact of network fluctuations, allowing your application to still be available when the network is unstable or even disconnected useSQRequest
Form submission strategy A hook designed for form submission. Through this hook, you can easily implement form drafts and multi-page (multi-step) forms. In addition, it also provides common functions such as form reset useForm
File upload strategy A simpler file upload strategy that supports automatic identification and conversion of base64, Blob, ArrayBuffer, and Canvas data useUploader
Send verification code Verification code sending hook reduces the complexity of developing the verification code sending function. useCaptcha
Automatically re-pull data Automatically re-pull data under certain conditions to ensure that the latest data is always displayed. useAutoRequest
Trigger requests across components An alova middleware that eliminates component-level restrictions and quickly triggers the operation function of any request in any component actionDelegationMiddleware
UseRequest for serial requests A more concise and easy-to-use serial request use hook than alova's serial request method, providing a unified loading status, error, callback function useSerialRequest
UseWatcher for serial requests A more concise and easy-to-use serial request use hook than alova's serial request method, providing a unified loading status, error, callback function. useSerialWatcher
Request retry strategy Automatic retry on request failure, which plays an important role on important requests and polling requests useRetriableRequest
SSE requests Requests via Server-sent Events useSSE

For more in-depth learning about Alova, please visit the Alova documentation. If you find Alova helpful, please star on GitHub repository.

If you find this article helpful, don't hesitate to like and comment. Share your thoughts on Alova or ask any questions you may have. Your support is our greatest motivation!

Join Our Community

If you have any questions, you can join our community chat groups or start discussions on the GitHub repository. If you encounter any issues, please submit them on GitHub's issues page, and we will address them promptly.

We also welcome contributions. For more information, please visit our contribution guidelines.

Top comments (0)