首页 > 解决方案 > ReasonReact useState 与获取的数据

问题描述

我已经使用 React 很长时间了,我想给 React 一个机会。然后我创建了一个小项目来从 Github 存储库中获取数据,然后显示结果。

我想使用 React Hooks 并将结果存储到我的状态中。

这是我正在尝试做的事情:

type githubRepo = {
  name: string,
  url: string,
};

module Decode = {
  let repo = (repo): githubRepo =>
    Json.Decode.{
      name: repo |> field("name", string),
      url: repo |> field("url", string),
    };
};

let useFetch = (~url: string, ~options=?, ()) => {
  let (loading, setLoading) = React.useState(() => true);
  let (result, setResult) = React.useState(() => []);

  React.useEffect1(
    () => {
      ignore(
        Js.Promise.(
          Fetch.fetch(url)
          |> then_(Fetch.Response.json)
          |> then_(json =>
               json
               |> Decode.repo
               |> (
                 decodedRepo => {
                   Js.log(decodedRepo);
                   setResult(result => decodedRepo);
                   setLoading(_ => false);
                   Some(decodedRepo);
                 }
               )
               |> resolve
             )
          |> catch(_err => resolve(None))
        ),
      );

      None;
    },
    [||],
  );

  (loading, result);
};

当我尝试这样做setResult(_ => decodedRepo)时会引发错误

这有类型:githubRepo 但在某个地方想要:list('a)

我知道我已经将我的 React.useState 初始化为一个空列表,但我不知道如何设置我的decodedRepo内部。

这是结果Js.log(decodedRepo)

Array [ "Node.js", "https://api.github.com/orgs/nodejs" ]
  0: "Node.js"
  1: "https://api.github.com/orgs/nodejs"
  length: 2

我还想知道是否有办法初始化 useState 没有价值?

标签: reactjsreact-hooksreasonreason-react

解决方案


您可以使用列表扩展语法将项目添加到列表中,类似于在 JavaScript 中的操作:

setResult(result => [decodedRepo, ...result]);

但是,如果您不想处理超过一项的可能性,则需要使用限制为零或仅一项的容器。这option类型。在使用中,它看起来像这样:

let (result, setResult) = React.useState(() => None);
setResult(result => Some(decodedRepo));

然后,当您使用时,result您将被迫处理它可能包含或不包含项目的可能性:

switch (result) {
| Some(decodedRepo) => ...
| None => ...
}

推荐阅读