【问题标题】:React Hooks ref.current is undefined during testReact Hooks ref.current 在测试期间未定义
【发布时间】:2020-08-22 05:48:42
【问题描述】:

TLDR - 我有一个使用 ref.current.offsetWidth 的响应式组件,但是当我使用 Jest 测试它时它不起作用

导航栏组件可以在 localhost 中正常工作和渲染。但是当我尝试使用 Jest 来刺激不同的屏幕宽度进行单元测试时,ref 挂钩由于某种原因无法获取 div 长度。有关如何解决此问题的任何建议?

错误: TypeError: Cannot read property 'offsetWidth' of undefined

代码:Navbar.js

// custom hook to get live div width 
const useContainerDimensions = myRef => {
  const getDimensions = () => ({
    width: myRef.current.offsetWidth,            //location of error
  });

  const [dimensions, setDimensions] = useState({ width: 0 });

  useEffect(() => {
    const handleResize = () => {
      setDimensions(getDimensions());
    };
    if (myRef.current) {
      setDimensions(getDimensions());
    }

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, [myRef]);

  return dimensions;
};

const Navbar = () => {
  const inputRef = useRef();
  const { width } = useContainerDimensions(inputRef);

  useEffect(() => {
    if (width >= 890) {
      setCurrTabPerRow(5);
      setTabStyle('5 tabs');
    }
    if (width < 890) {
      setCurrTabPerRow(4);
      setTabStyle('4 tabs');
    }
  }, [width]);

  return (
    ... 
    <div ref={inputRef}>
      //...stuff
    </div>
    ...
  )
}

export default Navbar;

navbar.test.js

const resizeWindow = (x, y) => {
  window.innerWidth = x;
  window.innerHeight = y;
  window.dispatchEvent(new Event('resize'));
}

describe('Navbar component', () => {
  it('should render', () => {
    const component = mount(
      <Navbar filter>
        <Navbar.Tab id="stuff1" />
        <Navbar.Tab id="stuff2" />
        <Navbar.Tab id="stuff3" />
      </Navbar>
    );
    act(() => {
      resizeWindow(500, 300);
    });
    expect(component).toMatchSnapshot();
  });
});

【问题讨论】:

    标签: javascript reactjs unit-testing jestjs react-hooks


    【解决方案1】:

    ref 的初始值未定义。在访问更多属性之前,您可以简单地检查 myRef.current 是否存在。并提供一个备用值。

    const getDimensions = () => ({
      width: (myRef.current && myRef.current.offsetWidth) || 0,
    });
    

    或使用可选链接

    const getDimensions = () => ({
      width: myRef?.current?.offsetWidth || 0,
    });
    

    【讨论】:

      【解决方案2】:

      useRef 钩子最初没有任何价值。你在声明它之后就传递了inputRef

      尝试做这样的事情:

      const [containerWidth, setContainerWidth] = useState(0);
      
      useEffect(() => {
        if(inputRef.current) {
          const { width } = useContainerDimensions(inputRef);
      
          setContainerWidth(width);
        }
      }, [inputRef])
      

      然后你确保inputRef 在传递给你的自定义钩子之前有一些价值。

      【讨论】:

        猜你喜欢
        • 2020-11-03
        • 2020-03-07
        • 1970-01-01
        • 2023-03-13
        • 2021-04-24
        • 2021-12-24
        • 2019-08-23
        • 2021-12-27
        • 2022-06-30
        相关资源
        最近更新 更多