如何解决使用React Hooks,使用“ useState”和“ useEffect”,是否有一种方法可以渲染状态,直到状态值出现?
我要做什么?
通过React Hooks将characterInfo
渲染到前端。
当前尝试执行此操作的代码是什么?
呈现信息的前端组件:
export default function ReactComponent() {
const [characterInfo,setCharacterInfo] = useState([]);
useEffect(() => {
socket.emit("/character/read");
socket.on("/character/read",function (data) {
if (data.status === "SUCCESS") {
setCharacterInfo(data)
}
});
return () => {
socket.off("/character/read");
};
},[]);
return (
<div>
{characterInfo.models[0].name}
</div>
)
}
后端.json
信息作为“数据”,以及由characterInfo
保存到setCharacterInfo
的内容:
{
status: "SUCCESS"
models: [
{
name: "AC",element: "Air",}
{
name: "Irene",element: "Fire",}
]
}
(因此,在这种情况下,访问“ AC”将为characterInfo.models[0].name
)
我期望结果如何?
我希望仅渲染AC
。
实际结果是什么?
我会收到此错误:
TypeError: Cannot read property '0' of undefined
我认为问题可能是什么?
我认为它必须处理异步平衡,尤其是useEffect()
。我认为前端会在setCharacterInfo
决定设置任何内容之前尝试渲染。
解决方法
我认为前端在setCharacterInfo决定甚至设置任何内容之前就尝试渲染。
是的,在运行useState
中的函数之前,组件将使用默认的useEffect
渲染一次。这是组件安装,更新和卸载时的执行顺序图(注意render
发生在useEffect
之前):
https://raw.githubusercontent.com/donavon/hook-flow/master/hook-flow.png
在访问characterInfo.models
之前,您需要检查name
是否存在(为了安全起见,请确保其长度)。
return (
<div>
{
characterInfo.models &&
characterInfo.models.length &&
characterInfo.models[0].name
}
</div>
)
或者,如果您使用的是可选链接:
return (
<div>
{characterInfo?.models[0]?.name}
</div>
)
另一个注意事项-您正在将characterInfo
的初始值设置为一个空数组。如果将其设为空对象,则可以清楚地看到您期望data
是一个对象,而不是数组。
const [characterInfo,setCharacterInfo] = useState({});
,
您可以将return语句调整为仅在存在名称时呈现名称
return (
<div>
{characterInfo.length && characterInfo.models[0].name}
</div>
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。