Это мой первый раз, когда я использую Redux Hooks в реакции.-нативно, но у меня возникают проблемы в моем тесте, потому что когда я запускаю тест, я получаю это предупреждение:
Предупреждение: React обнаружен изменение порядка хуков, вызываемых WarrantiesHomeButton. Это приведет к ошибкам и ошибкам, если не будет исправлено. Для получения дополнительной информации прочтите Правила зацепок:
Previous render Next render
------------------------------------------------------
1. useState useContext
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Я не уверен, что проблема в моем коде или в том, как я тестирую i, приложение работает нормально. Если я запускаю каждый тест независимо, тест проходит без предупреждения, если я запускаю все три теста, последний тест выдает предупреждение и ошибку.
Я был бы признателен, если бы вы, ребята, могли указать мне правильное направление, в котором я Я делаю ошибку.
ГарантииHomeButton. js
import React, { useState, useEffect, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { WarrantiesHomeMenu } from '../WarrantiesHomeMenu';
import { userService } from '../services';
import { HomeButton } from '../components';
import { screenNames } from '../constants';
import { userActions } from '../store';
import PropTypes from 'prop-types';
const WarrantiesHomeButton = ({ navigation }) => {
const [showWarrantiesMenu, setShowWarrantiesMenu] = useState(false);
const { warrantiesLoginFlow, user } = useSelector(
(state) => state.userReducer,
);
const dispatch = useDispatch();
const handlePressWarranties = () => {
if (!userService.isAuthenticated()) {
dispatch(userActions.warrantiesLoginStart());
navigation.navigate(screenNames.SIGN_UP);
} else {
setShowWarrantiesMenu(true);
}
};
useEffect(() => {
validateWarrantiesFlow();
});
const validateWarrantiesFlow = useCallback(() => {
if (warrantiesLoginFlow && user.id) {
setShowWarrantiesMenu(true);
dispatch(userActions.warrantiesLoginStop());
}
}, [warrantiesLoginFlow, user.id, dispatch]);
const handleModalPress = () => {
setShowWarrantiesMenu(false);
navigation.navigate(screenNames.SERVICE_CENTERS);
};
const closeWarrantiesHomeMenu = () => {
setShowWarrantiesMenu(false);
};
return (
<>
<HomeButton
testID="HomeButton"
text="Revisiones garantía"
icon="toolBox"
onPress={handlePressWarranties}
/>
<WarrantiesHomeMenu
visible={showWarrantiesMenu}
onPress={handleModalPress}
navigation={navigation}
closeModal={closeWarrantiesHomeMenu}
/>
</>
);
};
WarrantiesHomeButton.propTypes = {
navigation: PropTypes.objectOf(PropTypes.any),
};
export { WarrantiesHomeButton };
ГарантииHomeButton.test. js
import * as React from 'react';
import { Provider } from 'react-redux';
import {
render as rtlRender,
fireEvent,
wait,
act,
} from '@testing-library/react-native';
import { userService } from '../services';
import { screenNames } from '../constants';
import { WarrantiesHomeButton } from './WarrantiesHomeButton';
import { store } from '@auteco/store';
jest.mock('@auteco/components', () => require('@auteco/test').mockComponents());
jest.mock('../WarrantiesHomeMenu', () => {
const { mockComponent } = require('@auteco/test');
return {
WarrantiesHomeMenu: mockComponent('WarrantiesHomeMenu'),
};
});
describe('<WarantiesHomeButton/>', () => {
let mockProps;
const setState = jest.fn();
beforeAll(() => {
mockProps = {
navigation: {
navigate: jest.fn(),
dangerouslyGetParent: jest.fn(() => ({ state: null })),
},
};
jest.spyOn(userService, 'isAuthenticated').mockReturnValue(true);
});
function render(ui) {
return rtlRender(<Provider store={store}>{ui}</Provider>);
}
it('Should Render correctly', () => {
const { baseElement } = render(<WarrantiesHomeButton {...mockProps} />);
expect(baseElement).toMatchSnapshot();
});
describe('And user is authenticated', () => {
describe('And button is pressed', () => {
it('Should show WarrantiesMenu by setting setShowWarrantiesMenu state to true', async () => {
jest.spyOn(React, 'useState').mockReturnValue([false, setState]);
const { getByTestId } = render(<WarrantiesHomeButton {...mockProps} />);
const button = getByTestId('HomeButton');
button.props.onPress();
await wait();
expect(setState).toBeCalledWith(true);
});
});
});
describe('And user is not authenticated', () => {
describe('And button is pressed', () => {
it('Should navigate to signUpScreen', async () => {
jest.spyOn(userService, 'isAuthenticated').mockReturnValue(false);
jest.spyOn(React, 'useState').mockReturnValue([false, setState]);
const { getByTestId } = render(<WarrantiesHomeButton {...mockProps} />);
const button = getByTestId('HomeButton');
act(() => {
button.props.onPress();
});
expect(mockProps.navigation.navigate).toBeCalledWith(
screenNames.SIGN_UP,
);
});
});
});
});
ошибка в консоли
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:63
Warning: React has detected a change in the order of Hooks called by WarrantiesHomeButton. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks
Previous render Next render
------------------------------------------------------
1. useState useContext
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in WarrantiesHomeButton
in Provider
in View (created by View)
in View (created by AppContainer)
in View (created by View)
in View (created by AppContainer)
in AppContainer (at src/index.js:26)
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:63
The above error occurred in the <WarrantiesHomeButton> component:
in WarrantiesHomeButton
in Provider
in View (created by View)
in View (created by AppContainer)
in View (created by View)
in View (created by AppContainer)
in AppContainer (at src/index.js:26)
Consider adding an error boundary to your tree to customize error handling behavior.
FAIL src/components/home/WarrantiesHomeButton/WarrantiesHomeButton.test.js
<WarantiesHomeButton/>
✓ Should Render correctly (55ms)
And user is authenticated
And button is pressed
✓ Should show WarrantiesMenu by setting setShowWarrantiesMenu state to true (12ms)
And user is not authenticated
And button is pressed
✕ Should navigate to signUpScreen (77ms)
● <WarantiesHomeButton/> › And user is not authenticated › And button is pressed › Should navigate to signUpScreen
TypeError: Cannot read property 'length' of undefined
11 | const [showWarrantiesMenu, setShowWarrantiesMenu] = useState(false);
12 |
> 13 | const { warrantiesLoginFlow, user } = useSelector(
| ^
14 | (state) => state.userReducer,
15 | );
16 | const dispatch = useDispatch();
at areHookInputsEqual (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5703:38)
at updateMemo (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6336:11)
at Object.useMemo (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6703:16)
at useMemo (node_modules/react/cjs/react.development.js:1592:21)
at useSelectorWithStoreAndSubscription (node_modules/react-redux/lib/hooks/useSelector.js:31:41)
at useSelector (node_modules/react-redux/lib/hooks/useSelector.js:117:12)
at WarrantiesHomeButton (src/components/home/WarrantiesHomeButton/WarrantiesHomeButton.js:13:41)
at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5762:18)
at updateFunctionComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7579:20)
at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9152:16)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 1 passed, 1 total
Time: 4.846s, estimated 5s
Ran all test suites matching /WarrantiesHomeButton/i.
Watch Usage: Press w to show more.