我正在尝试创建一个方便的 react Hook ,以将 SVG 的 viewBox
与其内容相匹配。
import { useState } from 'react';
import { useEffect } from 'react';
import { useRef } from 'react';
// get fitted view box of svg
export const useViewBox = () => {
const svg = useRef();
const [viewBox, setViewBox] = useState(undefined);
useEffect(() => {
// if svg not mounted yet, exit
if (!svg.current)
return;
// get bbox of content in svg
const { x, y, width, height } = svg.current.getBBox();
// set view box to bbox, essentially fitting view to content
setViewBox([x, y, width, height].join(' '));
});
return [svg, viewBox];
};
然后使用它:
const [svg, viewBox] = useViewBox();
return <svg ref={svg} viewBox={viewBox}>... content ...</svg>
但是我收到以下 eslint 错误:
React Hook useEffect contains a call to 'setViewBox'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [viewBox] as a second argument to the useEffect Hook.eslint(react-hooks/exhaustive-deps)
到目前为止,我从未遇到过 React hooks eslint 错误“错误”的情况。我觉得这是对钩子(Hook)的完全合法的使用。它需要作为效果运行,因为它需要在渲染之后运行以查看 SVG 的内容是否已更改。至于警告消息:此代码已经避免了无限渲染循环,因为除非新值与当前值不同,否则 setState 不会触发重新渲染。
我可以禁用 eslint 规则:
// eslint-disable-next-line react-hooks/exhaustive-deps
但这似乎是错误的,我想知道是否有一种更简单/不同的方法来实现我没有看到的相同目标。
我可以让useViewBox
的调用者提供一些变量,这些变量将进入useEffect
的依赖数组并强制重新渲染,但我希望它是比这更灵活、更容易使用。
或者也许问题实际上在于exhaustive-deps
规则。如果它检测到 setState
前面的某些条件,也许它应该允许在无依赖项指定的 useEffect
中使用 setState
...
最佳答案
好吧,我找到了一个“解决方案”,灵感来自 this answer 。我认为这是一种愚蠢的解决方法,但我认为它比禁用 eslint 规则更好:
import { useState } from 'react';
import { useEffect } from 'react';
import { useRef } from 'react';
import { useCallback } from 'react';
// get fitted view box of svg
export const useViewBox = () => {
const svg = useRef();
const [viewBox, setViewBox] = useState(undefined);
const getViewBox = useCallback(() => {
// if svg not mounted yet, exit
if (!svg.current)
return;
// get bbox of content in svg
const { x, y, width, height } = svg.current.getBBox();
// set view box to bbox, essentially fitting view to content
setViewBox([x, y, width, height].join(' '));
}, []);
useEffect(() => {
getViewBox();
});
return [svg, viewBox];
};
关于reactjs - React "useViewBox"SVG viewBox 钩子(Hook)失败了 ESLint 规则详尽依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63961837/