Skip to content

Redux based hook doesn't get updated on store change #875

Open
@agawley

Description

@agawley
  • react-hooks-testing-library version: 7.0.2
  • react version: 17.0.1
  • react-dom version (if applicable): 17.0.1
  • react-test-renderer version (if applicable): 17.0.1
  • node version: 14.17
  • npm (or yarn) version: 8.4.0

Relevant code or config:

Hook:

export const useSettings = () => {
    const dispatch = useAppDispatch();
    const status = useAppSelector(selectSettingsStatus);
    const data = useAppSelector(selectSettings);
    useEffect(() => {
        if (status === 'idle') {
            dispatch(fetchSettings({}));
        }
    }, [status, dispatch]);
    const isUninitialized = status === 'idle';
    const isLoading = status === 'pending';
    const isError = status === 'failed';
    const isSuccess = status === 'succeeded';
    return { data, isUninitialized, isLoading, isError, isSuccess };
};

test:

it('should call the api and return response when status is idle', async () => {
        queryReturn = { status: 200, settings: TEST_SETTINGS };
        const initialSettingsData = {};
        const { store, result, waitFor } = renderHookWithContext(() => useSettings(), {
            initialState: { settings: { status: 'idle', data: initialSettingsData } },
        });
        expect(result.current.isUninitialized).toBe(true);
        store.subscribe(() => console.log('updating'));
        await waitFor(() => result.current.isSuccess, { timeout: 5000 });
        expect(result.current.data).toEqual(TEST_SETTINGS);
    });

Custom renderer

const renderHookWithContext = (
    hook,
    { initialState, store = configureStore({ reducer: rootReducer, preloadedState: initialState }) } = {}
) => ({
    store,
    ...renderHook(hook, {
        wrapper: ({ children }) => <Provider store={store}>{children}</Provider>,
    }),
});

What you did:

I am trying to test a ReactQuery-like Hook I have for my redux store. It looks at the store's status and dispatches a fetchSettings async action if it is idle while returning isLoading. When the data is loaded and updated in the store it returns isSuccess and the data.

What happened:

When I run the test I get a pass on the initial expect for isUnitialized but the hooks return values are never updated. Despite the fact that the store subscription shows logs that the store is updated 3 times as expected.

Problem description:

It looks like useSelector is not returning new updates to the store under the test - it does seem to work in my production component.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions