You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-testing-library测试Show more按钮点击后标签状态未更新如何解决

问题根因

你遇到的报错由两个核心问题导致:

  1. redux-mock-store 本身仅用于监听派发的action、验证动作是否正确触发,不会执行实际的reducer逻辑,所以你调用dispatch之后mockStore的state不会自动更新,组件读取到的currentCount、currentResult还是初始值。
  2. 你在点击按钮后直接同步执行断言,没有等待React内部状态更新(setPageCount是异步更新)和组件重渲染完成,也会导致断言拿到的是更新前的内容。
解决方案

方案1:使用真实Redux Store(更推荐,符合实际运行场景)

直接用你项目中真实的reducer创建store,而不是用mockStore,这样动作派发后会自动走reducer逻辑更新state,和线上运行逻辑完全一致,测试可信度更高。

import { createStore, combineReducers } from 'redux';
import searchReducer from '你的search reducer路径';

test('Show more button click works successfully', async () => {
  const rootReducer = combineReducers({
    search: searchReducer
  });
  const initialTestState = {
    search: {
      ...initialState.search,
      mainResult: SearchData.test.large,
      currentResult: SearchData.test.large.slice(0, 15),
      currentCount: 15,
      currentTotal: 16,
    },
  };
  // 用初始状态创建真实store
  const store = createStore(rootReducer, initialTestState);

  const { getByTestId, findByTestId } = render(
    <Provider store={store}>
      <SearchListing {...props} />
    </Provider>
  );
  const showMoreBtn = getByTestId('search-listing-result-footer-btn');

  expect(getByTestId('search-listing-result-footer-label')).toHaveTextContent('Showing 15 of 16 results');

  userEvent.click(showMoreBtn);
  // 等待更新完成后断言,findBy是异步查询,会自动等待元素内容更新
  expect(await findByTestId('search-listing-result-footer-label')).toHaveTextContent('Showing 16 of 16 results');
});

方案2:必须使用mockStore的处理方式

如果你的测试场景只需要验证动作派发正确、组件渲染和内部状态逻辑正确,可以手动等待状态更新后,验证派发的动作是否符合预期,再手动更新mockStore的state触发组件重渲染。

test('Show more button click works successfully', async () => {
  const state = {
    search: {
      ...initialState.search,
      mainResult: SearchData.test.large,
      currentResult: SearchData.test.large.slice(0, 15),
      currentCount: 15,
      currentTotal: 16,
    },
  };

  store = mockStore(state);
  const { getByTestId, rerender } = render(
    <Provider store={store}>
      <SearchListing {...props} />
    </Provider>
  );
  const showMoreBtn = getByTestId('search-listing-result-footer-btn');

  expect(getByTestId('search-listing-result-footer-label')).toHaveTextContent('Showing 15 of 16 results');

  userEvent.click(showMoreBtn);
  
  // 先验证派发的动作是否正确
  const actions = store.getActions();
  expect(actions[0].type).toBe('search/showMore'); // 替换成你实际的action type
  expect(actions[0].payload.currentCount).toBe(16);
  
  // 手动更新store的state,重新渲染组件
  const newState = {
    ...state,
    search: {
      ...state.search,
      ...actions[0].payload
    }
  };
  store = mockStore(newState);
  rerender(
    <Provider store={store}>
      <SearchListing {...props} />
    </Provider>
  );

  expect(getByTestId('search-listing-result-footer-label')).toHaveTextContent('Showing 16 of 16 results');
});
额外排查点

如果修改后还是有问题,可以检查这两个细节:

  • 确认pageCount的初始值是否为0,否则点击后newPageCount可能超出resultsChunk的下标范围,导致追加空数据
  • 确认resultsChunk的分块逻辑是否正确,第二块数据的长度是否为1

内容的提问来源于stack exchange,提问作者Alvinrightback

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:15:05