React使用useEffect校验白名单遇页面刷新状态丢失与路由跳转报错问题
问题修复方案
根因说明
- 页面跳转报错:直接给useEffect传入async函数是错误用法,async函数执行后默认返回Promise对象,而React要求useEffect只能返回函数类型的清理函数,框架尝试把返回的Promise当做函数调用时就会抛出
func.apply is not a function错误。 - 刷新后状态异常:刷新页面时
writeContracts、address这类web3相关实例还未完成初始化,此时writeContracts && writeContracts.Whitelist.isWhitelisted(address)会返回假值,导致最终查询结果为false;从其他页面跳转时web3实例已经在前置页面初始化完成,所以结果符合预期。
修复后代码
状态和异步逻辑部分
const [data, setData] = useState(null); const [loading, setLoading] = useState(true); async function doSomething() { // 前置判断依赖实例是否加载完成 if (!writeContracts?.Whitelist || !address) return false const result = await writeContracts.Whitelist.isWhitelisted(address); return result } async function test(){ const isWhitelisted = await doSomething() return !!isWhitelisted // 统一转换为布尔值返回 } useEffect(() => { // 异步函数定义在useEffect内部调用,不要直接给useEffect传async const fetchWhitelistStatus = async () => { try { setLoading(true); const dat = await test(); setData(dat); } catch (err) { console.error('白名单状态查询失败', err) setData(false) } finally { setLoading(false); } } fetchWhitelistStatus() // 依赖项添加web3相关实例,实例加载完成后自动重新触发查询 }, [writeContracts, address]);
渲染逻辑部分(可保留原有逻辑,也可优化为更严谨的写法)
if(loading) return <span>Loading</span> if (data === false) return <div>False</div> return <div>True</div>
内容的提问来源于stack exchange,提问作者Amnesia420
相关产品推荐
相关产品推荐

