reactjs - React "useViewBox"SVG viewBox 钩子(Hook)失败了 ESLint 规则详尽依赖

标签 reactjs react-hooks eslint

我正在尝试创建一个方便的 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/

相关文章:

reactjs - 为什么即使使用 ErrorBoundary 路由也会停止工作?

javascript - onClick 不适用于 <button> 但适用于 <a>

javascript - Cypress :有没有办法断言输入的值是否为空或至少有一定数量的字符

javascript - 有没有办法记住从参数传递的函数 - (useCallback) exhaustive-deps

javascript - 在 React 的 Div 中拖动图像时如何防止在新选项卡中打开

reactjs - 父组件如何在 React 中重置多个子组件

css - React Router 似乎会阻止自定义 CSS

reactjs - Jest 快照不匹配 - Windows 与 Unix/Linux 行尾

javascript - 如何修复react中eslint的 "Component is defined but never used"?

javascript - StandardJS linting 返回静态变量的解析错误