Estoy tratando de usar la biblioteca React-Redux y recibo el error en el título. Envolví mis componentes con Provider pero sigo recibiendo el error, solo si implemento el gancho useDispatch().
La aplicación funcionó bien, hasta que agregué la línea useDispatch(). El resto de líneas relacionadas con la función de envío se pueden eliminar y sigo teniendo el mismo error.
Si pudieras ayudarme te lo agradecería mucho. Gracias
Aquí está mi código:
import 'react-native-gesture-handler'; import {NavigationContainer} from '@react-navigation/native'; import Navigator from './navigation/Navigator'; import React, {useEffect, useState, useCallback} from 'react'; import {SafeAreaView, StyleSheet, Text, View} from 'react-native'; import {createStore, combineReducers} from 'redux'; import {Provider, useDispatch} from 'react-redux'; import dataReducer from './store/reducers/dataReducer'; import {CONSTANTS} from './constants/constants'; import {saveInitialData} from './store/actions/dataActions'; const App = () => { const [fetched, setFetched] = useState(initialState); const dispatch = useDispatch(); const saveInitialDataHandler = useCallback(data => { dispatch(saveInitialData(data)); callback; }, []); const rootReducer = combineReducers({ content: dataReducer, }); const store = createStore(rootReducer); useEffect(() => { fetchData(); }, []); const fetchData = () => { fetch(CONSTANTS.database) .then(response => response.json()) .then(responseJSON => { setFetched(true); saveInitialDataHandler(responseJSON); }); }; if (!fetched) { return ( <Provider store={store}> <View stlye={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text></Text> </View> </Provider> ); } else { return ( <Provider store={store}> <NavigationContainer> <SafeAreaView style={styles.SafeAreaView}> <Navigator></Navigator> </SafeAreaView> </NavigationContainer> </Provider> ); } }; const styles = StyleSheet.create({ SafeAreaView: {flex: 1}, }); export default App;La App debe estar envuelta en el proveedor ya que está usando useDispatch en ella. Ahora mismo es sólo un niño. El Provider establece el contexto para que solo sus hijos puedan tener acceso a él, no un padre.
Una solución sería crear un componente contenedor para él:
const AppWrapper = () => { const store = createStore(rootReducer); return ( <Provider store={store}> // Set context <App /> // Now App has access to context </Provider> ) } const App = () => { const dispatch = useDispatch(); // Works! ...tal vez importó Provider al archivo App.js. El proveedor debe importarse al archivo index.js.
/*index.js*/ import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { store } from './store/reduxStore'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById('root') );Si obtiene este error cuando ejecuta npm run test Entonces los problemas están relacionados con su archivo de prueba.
Actualice o reemplace su app.test.tsx por el siguiente código
NB: no olvide instalar redux-mock-store si aún no lo ha hecho.
import React from 'react'; import { render } from '@testing-library/react'; import App from './App'; import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; describe('With React Testing Library', () => { const initialState = { output: 10 }; const mockStore = configureStore(); let store; it('Shows "Hello world!"', () => { store = mockStore(initialState); const { getByText } = render( <Provider store={store}> <App /> </Provider> ); expect(getByText('Hello World!')).not.toBeNull(); }); });Obtuve esta solución después de buscar 1 hora. Muchas gracias a OSTE
Solución original: problemas de Github/8145 y enlace de solución
Con esta solución, si obtiene un error como TypeError: window.matchMedia no es una función , resuelva de esta manera. agregue esas líneas a su archivo setupTests.ts . Enlace de solución original stackoverflow.com/a/64872224/5404861
global.matchMedia = global.matchMedia || function () { return { addListener: jest.fn(), removeListener: jest.fn(), }; };