React useState实现hover效果时报错非组件/自定义Hook函数怎么解决?
报错原因
你违反了React Hooks的强制调用规则:Hooks仅允许在首字母大写的React函数组件、名称以use开头的自定义Hook中调用,你定义的renderHideOptionalClauseTrigger属于普通渲染工具函数,不符合上述要求,因此触发了ESLint校验报错。
第69行31列:React Hook "useState" 在函数 "renderHideOptionalClauseTrigger" 中被调用,该函数既不是React函数组件,也不是自定义React Hook函数,违反react-hooks/rules-of-hooks规则
解决方案
方案1:将函数改造为独立React组件(更推荐)
React函数组件要求首字母大写,改造后状态内聚在组件内部,复用性更强。
第一步:修改函数定义
// 首字母大写,成为合法React函数组件 const RenderHideOptionalClauseTrigger = () => { const [inHover, setHover] = useState(false); return ( <div className="my-option-clause"> <text>My Optional Loan Clause</text> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} > <path fill-rule="evenodd" clip-rule="evenodd" d="..."/> </svg> </div> ); };
第二步:修改组件调用方式
不要直接执行函数,改为传递组件实例:
<Collapsible trigger={<RenderHideOptionalClauseTrigger />} classParentString="opt-data" overflowWhenOpen="visible" triggerWhenOpen={<RenderHideOptionalClauseTrigger />} > {/* 原有子组件内容不变 */} </Collapsible>
方案2:将状态提升到上层LoanTerms组件
如果该悬浮状态需要和上层组件逻辑交互,可以把useState调用移到合法的React组件LoanTerms内部:
import React, { useState, useEffect } from "react"; import { useRouter } from "react-router-dom"; // 注意补充useRouter的引入 function LoanTerms(props) { const router = useRouter(); // 状态提升到上层组件 const [inHover, setHover] = useState(false); const { currentLoan, getUserLoanRequest, updateUserLoanProposalRequest, user, } = props; const renderHideOptionalClauseTrigger = () => { // 直接使用上层组件的状态和修改方法,无需在当前函数调用Hook return ( <div className="my-option-clause"> <text>My Optional Loan Clause</text> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} > <path fill-rule="evenodd" clip-rule="evenodd" d="..."/> </svg> </div> ); }; return ( <> <Collapsible trigger={renderHideOptionalClauseTrigger()} classParentString="opt-data" overflowWhenOpen="visible" triggerWhenOpen={renderHideOptionalClauseTrigger()} > <div className="FlowCard__info-text"> Will be added verbatim as last clause to the loan agreement. See{" "} <Link className="orange-link" to="/product"> Product page </Link>{" "} for other clauses. (1000 characters) </div> </Collapsible> </> ) }
内容的提问来源于stack exchange,提问作者Nhan Nguyen
相关产品推荐
相关产品推荐

