Reactstrap中能否使用useEffect内部声明的变量用于组件渲染?
问题核心说明
你无法直接在渲染逻辑中使用useEffect内部声明的变量,原因有两个:
- 变量存在作用域限制,你在useEffect回调内部用
var声明的data仅在该回调函数的作用域内有效,组件顶层的渲染逻辑无法跨作用域访问 - 即使你把
data提到组件顶层声明,普通JS变量的变更也不会触发React组件重新渲染,页面还是不会更新展示头像
解决方法
用React的useState响应式状态存储请求返回的用户数据即可,具体修改步骤如下:
- 先引入并声明响应式状态,用来存用户信息:
import { useEffect, useState } from 'react'; // 组件内声明状态,初始值可以设为null,也可以提前配置默认头像 const [userInfo, setUserInfo] = useState(null); const spoon = localStorage.getItem("true");
- 修改useEffect内的逻辑,请求完成后更新状态,同时修复原有代码的语法错误,替换阻塞页面的同步XHR为异步请求:
useEffect(() => { console.log(spoon) // 改用异步请求,避免阻塞主线程导致页面卡顿 const xmlHttp = new XMLHttpRequest(); xmlHttp.open('GET', `https://server.com/${spoon}`, true); // 第三个参数设为true代表异步 xmlHttp.setRequestHeader('AO', `Password ${PASS}`) xmlHttp.onload = function() { if (xmlHttp.status === 200) { const data = JSON.parse(xmlHttp.response); console.log(data.user.avatar) // 更新状态触发组件重新渲染 setUserInfo(data); } } xmlHttp.send() }, []);
- 渲染时加判空逻辑,避免请求未完成时访问属性报错:
return ( ... <DropdownToggle caret color="default" nav onClick={(e) => e.preventDefault()} > <div className="photo"> <img alt="用户头像" // 用可选链做判空,请求未返回时显示默认占位头像 src={userInfo?.user?.avatar || '默认头像占位地址'} /> </div> <b className="caret d-none d-lg-block d-xl-block" /> <p className="d-lg-none">Log out</p> </DropdownToggle> )
如果你坚持要保留同步请求的写法,只需要在原有useEffect里拿到data之后加一行setUserInfo(data)即可,渲染逻辑和上面一致,不过非常不推荐使用同步请求,会导致页面在请求完成前完全无法交互,体验极差。
内容的提问来源于stack exchange,提问作者noobcode0000
相关产品推荐
相关产品推荐

