hooks icon indicating copy to clipboard operation
hooks copied to clipboard

[v3]期望useRequest手动执行请求时,可以使用缓存数据

Open asyncguo opened this issue 3 years ago • 2 comments

image

import { message } from 'antd';
import React, { useState } from 'react';
import useRequest from '../../../';

function changeUsername(username: string): Promise<{ success: boolean }> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ success: true });
    }, 1000);
  });
}

export default () => {
  const [state, setState] = useState('');

  const { loading, run } = useRequest(changeUsername, {
    manual: true,
    onSuccess: (result, params) => {
      if (result.success) {
        setState('');
        message.success(`The username was changed to "${params[0]}" !`);
      }
    },
  });

const handleClick = () => {
  run(state)
}

  return (
    <div>
      <input
        onChange={(e) => setState(e.target.value)}
        value={state}
        placeholder="Please enter username"
        style={{ width: 240, marginRight: 16 }}
      />
      <button disabled={loading} type="button" onClick={handleClick}>
        {loading ? 'Loading' : 'Edit'}
      </button>
    </div>
  );
};

期望: 可以对搜索关键字state已请求过的数据进行缓存,不再进行接口请求 或者说是可以对接口请求的params进行缓存

asyncguo avatar Mar 31 '22 07:03 asyncguo

这个实现起来可能比较麻烦,可能要支持动态的 cacheKey。后面我考虑下这个能力。

brickspert avatar Mar 31 '22 09:03 brickspert

我的建议是从函数自记忆化下手,而不是使用useRequest

function memorizify(fn, judgeCachable = () => true) {
  const memorizedFn = function (...args) {
    const cacheMap = memorizedFn.cacheMap || memorizedFn.cacheMap = new Map();
    if (cacheMap.has(args)) {
      return cacheMap.get(args);
    }

    const res = fn.apply(this, args);

    if (judgeCachable(res))
      cacheMap.set(args, res);
     return res;
  }
  return memorizedFn;
}

SoonIter avatar Apr 16 '22 08:04 SoonIter