alibaba / hooks

A high-quality & reliable React Hooks library. https://ahooks.pages.dev/
https://ahooks.js.org/
MIT License
14.06k stars 2.71k forks source link

Error: url MUST be a string #386

Closed ihaichao closed 4 years ago

ihaichao commented 4 years ago

如果 service 是 string 、 object 、 (...args)=> string|object,则自动使用 umi-request 来发送请 求。

看到文档里 service 可以是一个 function,但是按照下面的用法会报错:

const { loading, run } = useRequest((value) => ({
    url: '/git/repo/list',
    method: 'get',
    params: {
      groupName: value
    }
  }), {
    onSuccess: (res: IResponse) => {
      setRepoList(res.data);
    }
  });
/**
 * 配置request请求时的默认参数
 */
const request = extend({
  errorHandler, // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

export default function(url: string, ...args: any[]) {
  return new Promise((resolve) => {
    request(url, ...args)
      .then((res: IResponse) => {
        if (!res.success) {
          notification.error({
            message: res.msg,
          });
          return;
        }
        resolve(res);
      })
      .catch(() => {});
  });
}

image

brickspert commented 4 years ago

你的 request 函数不对吧。

应该是

export default function({url, ...args}) {
}
ihaichao commented 4 years ago

直接用 umi-request 仍然会报同样的错

const { loading, run } = useRequest((value) => ({
    url: '/git/repo/list',
    method: 'get',
    params: {
      groupName: value
    }
  }), {
    onSuccess: (res: IResponse) => {
      setRepoList(res.data);
    }
  });
import { UseAPIProvider } from '@umijs/use-request';
import request from 'umi-request';

class App extends Component {
  render() {
    return (
      <ConfigProvider locale={zhCN}>
        <UseAPIProvider
          value={{ requestMethod: request }}
        >
          <Router>
            <Switch>
              <Route
                exact
                path="/"
              >
                <Redirect to={router[0].path} />
              </Route>
              {
                router.map(item => (
                  <Route
                    exact
                    key={item.path}
                    path={item.path}
                    component={item.component}
                  />
                ))
              }
            </Switch>
          </Router>
        </UseAPIProvider>
      </ConfigProvider>
    );
  }
}
brickspert commented 4 years ago

可以看下你的 umi hooks 版本号吗?

你可以在 request 函数打个日志,看看传递过来的 url 是什么。

ihaichao commented 4 years ago

@umijs/hooks: 1.9.2

在这里加了日志

var request = function request() {
  var initOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var coreInstance = new Core(initOptions);

  var umiInstance = function umiInstance(url) {
    console.log(url)
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var mergeOptions = mergeRequestOptions(coreInstance.initOptions, options);
    return coreInstance.request(url, mergeOptions);
  }; // 中间件

  ...
}

打印出来如图: image

YuGe commented 4 years ago

有新的说明吗?

brickspert commented 4 years ago

有新的说明吗?

如果有问题,可以提供个在线复现。

直接使用 umi-request 是不行的,需要手动把 url 拆分出来的。

liuwei0514 commented 4 years ago

const optionsRequest = useRequest( { url: '/xxgkArea/list', options: { method: 'POST', data: { level: 1 }, }, }, { initialData: [], }, );

<UseAPIProvider value={{ requestMethod: ({ url, options }) => request(url, options), }} >{children} </UseAPIProvider>

文档里是这样写的简单 requestMethod: request 实际使用需要构造下参数结构 requestMethod: ({ url, options }) => request(url, options),