【问题标题】:Reason-react rendering list of items from json来自json的Reason-react渲染项目列表
【发布时间】:2019-08-04 02:12:05
【问题描述】:

我正在学习理性反应,但无法呈现我从 json api 获取的项目列表。

let url = region => {
  "https://api.openbrewerydb.org/breweries?by_state="
  ++ Js.String.replaceByRe([%re "/\\s/g"], "_", String.lowercase(region));
};

[@react.component]
let make = (~region) => {
  let (breweries, setBreweries) = React.useState(() => []);

  React.useEffect1(
    () => {
      Js.Promise.(
        Axios.get(url(region))
        |> then_(response => {
             resolve(setBreweries(response##data));
           })
      );
      None;
    },
    [|region|],
  );

  let renderBrewery = brw => <div> {ReasonReact.string(brw##name)} </div>;

  <div>
    {breweries |> List.map(renderBrewery) |> Array.of_list |> React.array}
  </div>;
};

我正在取回我期望在 then_ 块中的数据。但是,当渲染项目时,我收到一个 JS 错误,提示 TypeError: brw is undefined,这意味着我收到的对象与我尝试渲染的对象之间存在差异。

【问题讨论】:

  • 您如何知道您在then_ 回调中收到了您期望的数据?
  • @glennsl Js.log 块中的Js.log 语句显示了我期望的数据
  • 您通过网络获取 JSON 数据,无论您使用纯 JavaScript 还是 ReasonML,您都需要在尝试访问数据之前验证(解码)数据。在 ReasonML 中尝试github.com/ryb73/ppx_decco 是一种简单的方法。

标签: reason bucklescript reason-react


【解决方案1】:

问题是(几乎可以肯定)您在数组上使用List.map

列表和数组不一样。数组 [|1, 2, 3|] 将在 JavaScript 中表示为普通数组,但列表 [1, 2, 3] 将表示为嵌套的二元素数组 [1, [2, [3, 0]]] ,每个数组(cons-cell)包含一个元素和一个指向下一个单元格,或0 作为终止符。

List.map 将继续迭代,直到遇到0 作为单元格的第二个元素,当然它永远不会这样做。相反,它会继续迭代垃圾数据,直到崩溃。

解决方案应该很简单,只需将 List.map 替换为 Array.map 并删除 Array.of_list,因为现在没有必要这样做了。

还值得注意的是,这可能已经通过类型注释来防止,而且几乎可以肯定的是使用 JSON 解码器。不得不花时间努力追查以发现这样的错误是您为方便动态键入所付出的代价。

【讨论】:

    猜你喜欢
    • 2021-03-20
    • 2019-05-03
    • 2021-03-21
    • 2012-10-20
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多