【问题标题】:React component does not re-render under Jest on state changeReact 组件在状态更改时不会在 Jest 下重新渲染
【发布时间】:2022-11-11 23:27:34
【问题描述】:

我的代码(我正在使用 React 路由器 v6):

零件:

const MyComponent = props => {
  const {price} = props;
  const location = useLocation();
  const result = useResult(price, location);

  return (
    <div>...</div>
  )
}     

自定义挂钩:

export const useResult = (price, location) => {
  const [result, setResult] = useState([]);

  useEffect(() => {
     const data = ...   //we build an array somehow
    setResult(data);        
  }, [price]);

  return result;
};

开玩笑测试:

  it('should ...',  () => {
    render(
      <BrowserRouter>
        <MyComponent price={300}/>);
      </BrowserRouter>
    )
    
    expect(...).toBeInTheDocument();
  });

上面的代码确实发生了MyComponent运行测试时, 只渲染一次而不是两次(当应用程序运行时)。在result 是一个空数组的初始渲染之后,useResultuseEffect 正在运行,并且由于状态发生了变化,我应该期望MyComponent 被重新渲染。然而,事实并非如此。对此的任何解释?

【问题讨论】:

  • const data = ... //we build an array somehow - 这是同步操作吗?
  • 是的。它是一个同步的。
  • 测试是同步的,React 状态更新是同步的不是同步处理。测试需要等待组件使用您尝试断言的任何更新的 UI 重新呈现。
  • 好的。但是,我的问题的答案是什么?调试测试时,不会重新渲染组件。为什么?
  • 从用户的角度来看,您的测试目标是什么?用户不会真正关心它重新渲染了多少次。我建议填写代码并进行更多测试,以便让我们更深入地了解您实际尝试测试的内容。

标签: reactjs jestjs react-router react-testing-library


【解决方案1】:

你可以做:

The test will have to be async: it('should ...',  async() => { ....

await screen.findByText('whatever');
This is async so it will wait to find whatever and fail if it can't find it

or you can do
await waitFor (() => {
   const whatever = screen.getByText('whatever');
   expect(whatever).toBeInTheDocument();
})

【讨论】:

    猜你喜欢
    • 2018-03-17
    • 2019-02-27
    • 2020-03-03
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多