如何向自定义Hook传递return语句中的参数,解决Hook非法调用报错
报错原因
你触发错误是违反了React Hook的强制调用规则:所有Hook必须在React函数组件的顶层作用域调用,禁止在return的JSX内部、循环、条件判断、普通自定义函数中调用。你把useGeo封装在getAddApi函数中,又在JSX渲染阶段调用,等于将Hook放到了渲染逻辑里执行,自然触发非法调用报错。
正确实现方案
根据你的使用场景分两种处理方式:
场景1:列表循环渲染多个带经纬度的条目
将单个列表项拆成独立的子组件,在子组件顶层调用useGeo:
// 拆分独立的列表项子组件 const AddressItem = ({ latitude, longitude }) => { // 子组件顶层调用自定义Hook,符合调用规则 const { geodata, isPending, geoerror } = useGeo(latitude, longitude); if (isPending) return <Text>加载地址中...</Text>; if (geoerror) return <Text>地址加载失败</Text>; return <Text>{geodata}</Text>; };
父组件列表渲染时直接引用子组件即可:
// 父组件渲染逻辑 { list.map(item => ( <AddressItem key={item.id} latitude={item.latitude} longitude={item.longitude} /> )) }
场景2:仅单个经纬度需要解析地址
直接在组件顶层调用useGeo即可,无需封装额外函数:
// 组件顶层调用,传入目标经纬度参数 const { geodata: address, isPending, geoerror } = useGeo(latitude, longitude); // return内直接使用变量 return <Text>{address}</Text>
补充注意
你需要确认自定义HookuseGeo内部已经监听了经纬度参数的变化,参数更新时会自动重新请求数据,参考示例:
function useGeo(lat, lon) { const [geodata, setGeodata] = useState(null); const [isPending, setIsPending] = useState(false); const [geoerror, setGeoerror] = useState(null); useEffect(() => { // 跳过无效经纬度的请求 if (!lat || !lon) return; setIsPending(true); // 此处替换为你的地理数据请求逻辑 fetchGeoData(lat, lon) .then(res => setGeodata(res)) .catch(err => setGeoerror(err)) .finally(() => setIsPending(false)); }, [lat, lon]); // 监听经纬度参数变化触发更新 return { geodata, isPending, geoerror }; }
内容的提问来源于stack exchange,提问作者Nelson Adeyinka
相关产品推荐
相关产品推荐

