调用API并更新状态后,访问数组元素属性返回undefined
解决:访问状态中对象属性返回Undefined的问题
嘿,我之前在ReasonReact项目里也碰到过一模一样的坑!这种情况几乎可以肯定是API返回的JSON没有被正确解析成可直接访问属性的类型,虽然控制台打印看起来是普通对象,但实际上它是ReasonML包装后的原始JSON值(Js.Json.t类型),直接用.访问自然拿不到属性。
为什么会出现这种矛盾?
当你打印self.state.projects[0]时,浏览器控制台会自动展开这个JSON值,给你显示它的结构,但这只是控制台的“善意美化”——在Reason的类型系统里,这个值并不是一个拥有name属性的普通JS对象,而是一个未解析的JSON节点。所以当你尝试用.name访问时,编译后的JS代码找不到对应的属性,就返回undefined了。
具体解决步骤
1. 定义对应的类型并编写解析函数
首先,我们需要把API返回的JSON结构映射成Reason能识别的记录类型,然后写解析函数把原始JSON转成这个类型:
// 定义项目的类型 type project = { name: string, }; // 解析单个项目对象 let parseProject = json => { open Js.Json; name: json |> decodeObject |> getExn("name") |> decodeString |> getExn }; // 解析整个API响应 let parseApiResponse = json => { open Js.Json; json |> decodeObject |> getExn("data") |> decodeArray(parseProject) |> getExn };
2. 在didMount中解析数据后再更新状态
不要直接把API返回的原始JSON存进状态,先通过上面的解析函数处理一下:
componentDidMount(self) => { fetch("/your-api-endpoint") |> Js.Promise.then_(response => response |> Response.json()) |> Js.Promise.then_(rawJson => { // 先解析数据 let parsedProjects = parseApiResponse(rawJson); // 再更新状态 self.update(state => {...state, projects: parsedProjects}); Js.Promise.resolve(); }) |> ignore; };
3. 验证属性访问
现在你再点击按钮执行Js.log(self.state.projects[0].name),就能正确打印出"Flaherty"了。
额外的小建议
为了避免数组为空时的报错,可以在打印前加个简单的判断:
onClick: (_) => { switch self.state.projects { | [] => Js.log("还没有加载到项目数据哦") | [firstProject, ..._] => Js.log(firstProject.name) } }
内容的提问来源于stack exchange,提问作者benschinn
相关产品推荐
相关产品推荐

