我正在学习 Reason React,但在渲染从 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_
block 中取回我期望的数据。然而,当渲染这些项目时,我收到一个 JS 错误,提示 TypeError: brw is undefined
,这意味着我收到的对象和我尝试渲染的对象之间存在差异。
最佳答案
问题是(几乎可以肯定)您正在数组上使用 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 解码器来防止。必须花时间跟踪像这样难以捕获的错误,这是您为动态类型的便利性付出的代价。
关于Reason-react 渲染来自 json 的项目列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57343312/