完美兼容react的请求神器,入门看这篇就够了

alova是一个轻量级的请求策略库,旨在简化接口的管理和使用。你可以通过简单配置参数,即可实现复杂请求如请求共享、分页请求、表单提交、断点续传等,无需编写大量代码,提高开发效率,应用性能,减轻服务端压力。

使用alovajs后,你只需要选择对应的useHook进行请求即可,alova同时支持vue/react/svelte框架。如果你也喜欢 alovajs,请在Github 仓库中贡献一颗 star,这对我们非常重要。

这篇文章作为react+alova的基础入门篇,你可以了解到以下内容:

  1. alova如何优雅地处理频繁请求、模糊搜索
  2. alova如何协助管理react项目下的服务端状态
  3. alova顺滑的使用方式

欢迎加入交流社区

有任何使用问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。

同时也欢迎贡献你的一份力量,请移步贡献指南

安装alova

bash 复制代码
npm install alova --save-dev

初始化一个alova实例

在接下来的入门指南中,我们会以待办事项(todo)为例,围绕着获取不同日期的待办事项列表、查看todo详情,以及创建、编辑、删除事项等需求进行讲解!

一个alova实例是使用的开端,所有的请求都需要从它开始。它的写法类似axios,以下是一个最简单的alova实例的创建方法。

javascript 复制代码
import { createAlova } from 'alova';
import GlobalFetch from 'alova/GlobalFetch';
import ReactHook from 'alova/react';
const alovaInstance = createAlova({
  // 假设我们需要与这个域名的服务器交互
  baseURL: 'https://api.todo.com',

  // ReactHook用于创建ref状态,包括请求状态loading、响应数据data、请求错误对象error等
  statesHook: ReactHook,

  // 请求适配器,这里我们使用fetch请求适配器
  requestAdapter: GlobalFetch(),
  
  // 设置全局的请求拦截器,与axios相似
  beforeRequest(config) {
    // 假设我们需要添加token到请求头
    config.headers.token = 'token';
  },

  // 响应拦截器,也与axios类似
  async responsed(response, config) => {
    const json = await response.json();
    if (json.code !== 200) {
      // 这边抛出错误时,将会进入请求失败拦截器内
      throw new Error(json.message);
    }
    return json.data;
  },
});

todo列表 - 直接使用alova管理的状态进行界面渲染

此demo中我们的界面长这样。

我们使用useRequest发送请求,它是页面获取初始化数据时最常用的方法。

jsx 复制代码
const todoListGetter = alovaInstance.Get('/todo/list');
export const TodoList = () => {
    const {
    // loading是加载状态值,当加载时它的值为true,结束后自动更新为false
    // 它是一个Ref类型的值,你可以通过loading.value访问它,或直接绑定到界面中
    loading,

    // 响应数据
    data: todoList,

    // 请求错误对象,请求错误时有值,否则为undefined
    error,

    // 成功回调绑定
    onSuccess,

    // 失败回调绑定
    onError,

    // 完成回调绑定
    onComplete,

    // 直接将Method对象传入即可发送请求
  } = useRequest(todoListGetter, {
    // 初始data数据
    initialData: [],
  });

  // ###### 回调设置
  onSuccess(todoListRaw => {
    console.log('请求成功,响应数据为:', todoListRaw);
  });
  onError(error => {
    console.log('请求失败,错误信息为:', error);
  });
  onComplete(() => {
    console.log('请求完成,不管成功失败都会调用');
  });
  
  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列表页 - 更改为可模糊搜索todo项

模糊搜索功能就是,在输入关键字过程中不断发出请求,此时我们将上面的useRequest替换为useWatcher以实现关键词变化自动重新获取数据。

为了提升用户体验,减小服务端压力,我们还实现了搜索防抖。

实现代码如下:

jsx 复制代码
export const TodoList = () => {
  // ...省略重复代码

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

  // 将useRequest替换为useWatcher
  // 通过useWatcher监听keyword变化,变化后自动重新发出请求
  const [keyword, setKeyword] = useState('');
  const {
    loading,
    error,
    data,
  } = useWatcher(() => searchTodo(keyword), [keyword], {
    debounce: 500, // 设置500毫秒请求级防抖,无需自己实现防抖功能
  });

  return // ...视图代码和上面相同
};

这样就实现了带防抖的模糊搜索功能。

todo编辑页 - 将频繁请求的数据做内存缓存

编辑页是这样的:

获取编辑页数据并回显

这里我们的场景需要考虑,用户在数秒内多次点击某个todo项进行查看,每次进入都请求服务器显得有点浪费,此时我们可以做一层前端缓存,来提高展示速度,减少服务端压力。

jsx 复制代码
const todoDetail = id => alovaInstance.Get(`/todo/${id}`, {
    // 设置5分钟的本地内存缓存,刷新即失效
    localeCache: 5 * 60 * 1000,
});
export const TodoDetail => ({ id }) => {
  const {
    loading,

    // 响应数据
    data: todoDetail,
    update
  } = useRequest(todoDetail(params.id));

  const handleAddTodo = () => {
    // 继续往下看
  }

  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}>提交数据</button>
    </div>
  )
}

数据提交代码 - 手动更新todo列表数据

接下来我们来看看提交数据的操作,我们希望它在提交成功后直接跨组件更新todo列表的数据,而不是再一次请求数据刷新界面。

jsx 复制代码
export const TodoDetail = ({ id }) => {
  // ...
  // 首先新建一个提交数据的请求,并将immediate设置为false,这样初始化时不会发送请求
  const createTodoPoster = newTodo => alova.Post('/todo', newTodo);
  const {
    loading: submiting,
    data,
    error,

    // 手动发送器请求的函数,调用后发送请求
    send: submitTodo,
  } = useRequest(() => createTodoPoster(todoDetail), {
    // 当immediate为false时,初始化时不再发出请求
    immediate: false
  });

  // 触发提交请求
  const handleAddTodo = () => {
    submitTodo()
      .then(result => {
        // 更新列表数据,获取todo列表状态,返回更新后的数据
        updateState(todoDetail(params.id), todoListData => {
            const index = todoListData.findIndex(({ id }) => id === params.id);
            todoListData[index] = todoDetail.value;
            return todoListData;
        });
      })
      .catch(error => {
        console.log('新增todo项失败,错误信息为:', error);
      });
  };

  return (
    <div>
      {/*... */}
      <button loading={submiting} onClick={handleAddTodo}>提交数据</button>
    </div>
  )
}

结尾

现在,你还可以在 vue2 的 options 写法中使用 alova 了,点击查看详情

这里还有超多可运行的示例

如果觉得文章对你有帮助,请别吝啬你的赞和评论哈,说说你对 alovajs 怎么看的,或者可以问一些问题,我会尽量回答的,你的支持是我创作的最大动力!哈哈哈哈哈哈~

想学习更多 alovajs 的用法,欢迎来alova 官网学习。如果你也喜欢 alovajs,请在Github 仓库中贡献一颗 star,这对我们非常重要。

欢迎加入交流社区

有任何问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。

同时也欢迎贡献你的一份力量,请移步贡献专区

往期文章

相关推荐
joan_8515 分钟前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
还是大剑师兰特38 分钟前
什么是尾调用,使用尾调用有什么好处?
javascript·大剑师·尾调用
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
燃先生._.9 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖10 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
black^sugar11 小时前
纯前端实现更新检测
开发语言·前端·javascript
2401_8576009512 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_8576009512 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js