React 挂钩和比较对象引用

问题描述 投票:0回答:1

我在实现自己的钩子时陷入了“太多重新渲染”陷阱。钩子本身看起来像这样: function useRegexValidate(value: string, regex: RegExp, errorMessage: string, deps: any[] = []): ValidationResult { const [result, setResult] = useState<ValidationResult>(ValidationResult.Valid); useEffect(() => { if (!regex.test(value)) { setResult(new ValidationResult(false, errorMessage)); } else { setResult(ValidationResult.Valid); } }, [value, regex, errorMessage, ...deps]) return result; }

查找起来有点棘手,但错误的根源是将正则表达式作为 
RegExp

传递。在每次渲染期间,都会创建

RegExp
对象的单独实例,从而导致重新渲染,在此期间创建另一个实例 - 依此类推。
我通过将正则表达式作为字符串传递来解决这个问题:

function useRegexValidate(value: string, regex: string, errorMessage: string, deps: any[] = []): ValidationResult { const [result, setResult] = useState<ValidationResult>(ValidationResult.Valid); useEffect(() => { let regexObj = new RegExp(regex); if (!regexObj.test(value)) { setResult(new ValidationResult(false, errorMessage)); } else { setResult(ValidationResult.Valid); } }, [value, regex, errorMessage, ...deps]) return result; }

我想我也可以通过不就地传递正则表达式来解决这个问题,而是创建一个常量值(因为表达式不太可能改变),例如

const regex: RegExp = /.../; useRegexValidate(..., regex, ...);

但这会妨碍我的钩子的用户友好性,因为人们需要记住以特定的方式调用它,以免导致难以跟踪错误。所以这绝对不是一个选择。

我不太喜欢我选择的解决方案,因为每次执行验证时都需要创建 RegExp 对象。有没有办法以某种方式教 React 比较特定对象的内容而不仅仅是它们的引用?

有更好的方法来修复我的初始代码吗?

reactjs typescript react-hooks
1个回答
0
投票
通常,当我有想要用作 deps 的对象时,我的解决方案是对它们进行 JSON.stringify。这样你就可以保持 RegExp 的类型安全。

© www.soinside.com 2019 - 2024. All rights reserved.