React中if判断调用组件比对值失败及Hook调用错误解决方案求助
问题核心错误点
- 最初的判断逻辑本质错误:
<GetAssetTypeNameComponent datafromparent = {assettype_assettypeId}/>是React生成的虚拟DOM对象,和字符串"Tower"类型完全不同,判断永远返回false,这是最开始逻辑不生效的根本原因。 - 违反Hook调用规则:你在类组件的事件回调
editAssets中直接调用了带useState的函数组件GetAssetTypeNameFunction,Hook只能在React函数组件的顶层作用域、或者自定义Hook中调用,普通函数/类方法/事件回调中调用都会触发Invalid hook call报错。 - 改造后的函数组件本身存在多个Bug:
- 接口请求直接写在组件顶层,没有用
useEffect包裹,每次组件渲染都会重复触发请求 assetType初始值为undefined,直接调用map方法会抛出类型错误- 组件返回的是
<ul>包裹的JSX对象,不是纯文本字符串,就算调用逻辑正确,也不可能和"Tower"相等
- 接口请求直接写在组件顶层,没有用
解决方案
你当前的场景是需要在事件回调中判断资产类型名称,不需要渲染组件,最合理的方案是把接口请求和组件逻辑解耦,单独封装工具函数:
步骤1:封装可复用的异步工具函数
// 可以放到单独的utils文件中全局复用 import AssetTypeService from './AssetTypeService' export const getAssetTypeNameById = async (id) => { const res = await AssetTypeService.getAssetTypeById(id); return res.data.assettypeName; }
步骤2:改造事件回调为异步方法
async editAssets(assetsid,assettype_assettypeId){ const typeName = await getAssetTypeNameById(assettype_assettypeId); if (typeName === "Tower") { this.props.history.push(`/add-assetstower/${assetsid}/${this.props.match.params.sitemasterid}`); } }
(可选)保留渲染用组件的优化方案
如果有其他场景需要渲染资产类型名称,可以基于上面的工具函数封装组件,避免重复代码:
import React, { useState, useEffect } from 'react'; import { getAssetTypeNameById } from './utils' const GetAssetTypeNameComponent = (props) => { const { id } = props; const [name, setName] = useState(''); const [loading, setLoading] = useState(true); useEffect(() => { const fetchName = async () => { const res = await getAssetTypeNameById(id); setName(res); setLoading(false); } fetchName(); }, [id]); if(loading) return <div>加载中</div>; return <div>{name}</div>; } export default GetAssetTypeNameComponent;
内容的提问来源于stack exchange,提问作者HighwayRob
相关产品推荐
相关产品推荐

