Unable to handle error: `middleware is not a function' in redux-promise-middleware? - react-native

I am trying to use redux-promise-middleware in my app, but when I am trying to run my app error comes with an error message: 'middleware is not a function or middleware is null'.
I tried to use middleware without a function as suggested in redux async docs, but still error is coming.
configureStore.js
import { createStore, applyMiddleware } from 'redux'
import app from './reducers/index';
import PromiseMiddleware from 'redux-promise-middleware';
const configureStore = () => {
let middleware = applyMiddleware(PromiseMiddleware());
let store = createStore(app, middleware);
return store
};
export default configureStore;
index.js
import React from 'react'
import { AppRegistry } from 'react-native';
import App from './App';
import { Provider } from 'react-redux'
import configureStore from './configureStore'
const store = configureStore();
const ReduxMiddleware = () => {
<Provider store={store}>
<App />
</Provider>
}
AppRegistry.registerComponent('ReduxMiddleware', () => ReduxMiddleware);
Please anybody, suggest to me that why I am facing this error.
I am new to redux.

import promiseMiddleware from 'redux-promise-middleware';
composeStoreWithMiddleware = applyMiddleware(
promiseMiddleware,
)(createStore);
And not : PromiseMiddleware()
(not uppercase and w/o () )

Related

PersistGatae causes Cannot read property 'subscribe' of undefined error

I am trying to figure put how to use Redux-Persist. I have the following code in my index.js:
import { AppRegistry, View } from "react-native";
import React from "react";
import App from "./App";
import { name as appName } from "./app.json";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import storeConfig from "./app/config/store";
const AppRedux = () => (
<Provider store={storeConfig.store}>
<PersistGate presistor={storeConfig.persistor} loading={null}>
<App />
</PersistGate>
</Provider>
);
AppRegistry.registerComponent(appName, () => AppRedux);
When I run it I get the following message:
Unhandled JS Exception: TypeError: Cannot read property 'subscribe' of undefined
BUT, When i comment out PersistGate I have no problems and my store gets rehydrated.
The reason I am trying to keep PersistGate is to have splash screen while rehydrating. Any suggestions on how to solve this problem?
P.S. This is what I have in store file:
export default () => {
const pReducer = persistReducer(persistConfig, reducers);
const store = createStore(pReducer, {}, applyMiddleware(logger));
const persistor = persistStore(store);
return { store, persistor };
};

Could not find "store" in the context of "Connect(App)" even after uses provider or connect

I'm trying to use redux in my project I make my code like tutorial but it won't work and give error
I see most of the question about this error but I already done what they say the soultion like I should warp my root componet with provider or use connect
Invariant Violation: Could not find "store" in the context of "Connect(App)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(App) in connect options.
index.js
import React from 'react';
import {AppRegistry} from 'react-native';
import {Provider} from 'react-redux';
import App from './App';
import { name as appName } from './app.json';
import placesReducer from './src/store/reducers/places';
import{createStore} from 'redux'
import configureStore from './src/store/configureStore';
const store = configureStore();
const RNRedux = () => (
<Provider store={store}>
<App/>
</Provider>
);
AppRegistry.registerComponent(appName, () => RNRedux);
APP.js
import React, { Component } from "react";
import { StyleSheet, View } from "react-native";
import { connect } from "react-redux";
class App extends Component {
render() {
return (
<View style={styles.container}>
some code
</View>
);
}
}
const mapStateToProps = state => {
return {
some code
};
};
const mapDispatchToProps = dispatch => {
return {
some code
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
my store
import {combineReducers, createStore} from 'redux';
import placesReducer from './reducers/places';
const rootReducer = combineReducers({
places: placesReducer
});
const configureStore = () => createStore(rootReducer)
export default configureStore;
const configureStore = () => createStore(rootReducer)
configureStore in this case is a variable with the return value of createStore, you most likely want it to be a function.
do you have to call configureStore as callback?
can you call it directly like that:
const configureStore = createStore(rootReducer);

React Naitve Redux getState Undefined

I am trying to Firebase Phone Authentication with React-redux. but i am getting getState undefined in Action file.
i am getting "confirmResult.confirm is undefined"
Action.Js
const onCodeDispatched = (code) => {
return (dispatch, getState) => {
console.log(getState())
getState().auth.confirmResult.confirm(code)
.then(user => onLoginSuccess(dispatch, user))
.catch(error => onCodeConfirmError(dispatch, error));
}
}
App.js
import React from 'react'
import {Provider} from 'react-redux'
import {createStore, applyMiddleware, compose} from 'redux'
import thunkMiddleware from 'redux-thunk'
import reducers from '../reducers'
import App from './App'
import {persistStore} from 'redux-persist'
import {PersistGate} from 'redux-persist/es/integration/react'
const middleware = [thunkMiddleware]
const store = compose(applyMiddleware(...middleware))(createStore)(reducers)
console.log(store)
let persistor = persistStore(store)
class Root extends React.PureComponent {
render() {
return (
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>
)
}
}
export default Root
i am new in react-redux it is very confusing me i already read many articles i already spent many days finding the error can you please give me some idea why getState is returning Undefined.
Try to split how are you constructing the store. You can begin creating just a simple instance of store, like this:
const store = createStore(reducers, yourInitialState)
Then print the store and see what happened. If everything is okay, try to use compose, applyMiddleware, and thunk like that:
const store = createStore(
reducer,
compose(
applyMiddleware(thunk),
DevTools.instrument() // this is a really helpful instrument
)
)
If you have doubts just ask or follow the official doc from Redux website

React Navigation v 2 and Redux

I have been using react-native-router-flux in my app and configured the store and it works like a charm.
I am now planning to use react-navigation v2.8 in my app and i am struggling to complete the configureStore.
I supposed that the configureStore would be used as is from the react-native-router-flux example. Below is the sample code from my working react-native-router-flux sample.
/* global __DEV__ */
import { Router } from 'react-native-router-flux'; //this is not to be used
in react-navigation
import { connect } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore } from 'redux-persist';
import ReduxPromise from 'redux-promise';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';
import reducers from './index';
connect()(Router); //ROuter is not avaible in react-navigation
let middleware;
if (__DEV__) {
const logger = createLogger();
middleware = [thunk, ReduxPromise, logger];
//middleware = [thunk, ReduxPromise];
} else {
middleware = [thunk, ReduxPromise];
}
export function configureStore() {
const store = compose(applyMiddleware(...middleware))(
createStore
)(reducers);
const persistor = persistStore(store);
return { persistor, store };
}
export const { persistor, store } = configureStore();
React Navigation can be used as a general JSX Component that can be enclosed within the Provider and thus the whole UI tree will have the store available inside the context. So you can just initialize the store in your app's root, keep it as a state variable inside
it and pass it to the context using Provider.
Code for configuring your store and making it available down in your UI tree made using React Navigation should look like below:
Your Root component should look like this
import React, {Component} from 'react';
import {Provider} from 'react-redux';
import AppStack from './app/AppNavigation';
import getStore from './app/store';
export default class App extends Component {
constructor (props) {
super(props);
this.state = {
store : getStore()
}
}
render() {
return (
<Provider store={this.state.store} >
<AppStack /> . // This is your React Navigation Stack.
</Provider>
);
}
}
and your getStore should look like this:
import { createStore } from 'redux';
import reducers from './reducers';
export default function getStore () {
const enhancer = compose(
applyMiddleware(
//your middlewares here..
)
);
const store = createStore(reducers);
return store;
}
and the AppStack can look like this:
import {createStackNavigator} from 'react-navigation';
import FirstScreen from './components/FirstScreen';
export default AppStack = createStackNavigator({
Screen1: {
screen: FirstScreen,
//other routes....
},
});
This is just a mere simplest possible example.

Persist store with Redux Toolkit in React-native

I am using redux-persist with redux toolkit.
here is my store configuration.
I haven't implemented or configured store before.
I intend to persist user state after login.
Currently after login, if I reload app in emulator it always goes back to login screen.
is my store configured properly?
updated store file:
import {configureStore} from '#reduxjs/toolkit';
import authReducer from '../features/login/authSlice';
import AsyncStorage from '#react-native-community/async-storage';
import {persistReducer, persistStore} from 'redux-persist';
import {combineReducers} from 'redux';
import hardSet from 'redux-persist/lib/stateReconciler/hardSet';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const reducers = combineReducers({
auth: authReducer,
// other reducers goes here...
});
const persistConfig = {
key: 'root',
storage: AsyncStorage,
// stateReconciler: hardSet,
};
const _persistedReducer = persistReducer(persistConfig, reducers);
export const store = configureStore({
reducer: _persistedReducer,
});
export const persistor = persistStore(store);
My index.js file where i wrap my root component with PersistGate
import React from 'react';
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import {store, persistor} from './src/stores/store';
import {Provider} from 'react-redux';
import {storeUser, storeRefreshToken} from './src/features/login/authSlice';
import {PersistGate} from 'redux-persist/lib/integration/react';
const RNRedux = () => (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
AppRegistry.registerComponent(appName, () => RNRedux);
Error I get currently:
I think you need to use persistStore. You should store your app store in persistStore and then use persistGate.
PersistGate delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux.
So, your store file can be :
import { persistStore } from 'redux-persist';
const persistor = persistStore(store);
export { persistor, store };
And your app.js will be :
import { store, persistor } from 'path_to_your_store/store';
<Provider store={store}>
<PersistGate persistor={persistor}>
</App>
</PersistGate>
</Provider>
This appears to be an issue with redux-persist passing a function as an action type which is not recommended by the Redux devs. Redux Toolkit was developed with defaults to help avoid the creation of breakable code. It's RTK's default middleware "serializableCheck" that throws this error. This middleware can be disabled outright or just for specific actions, and both methods are provided by example in answers to this SO question. RTK middleware documentation here for quick reference.
Here's a blanket solution that should work for you:
- import {configureStore} from '#reduxjs/toolkit';
+ import {configureStore, getDefaultMiddleware} from '#reduxjs/toolkit';
...
export const store = configureStore({
reducer: _persistedReducer,
+ middleware: getDefaultMiddleware({
+ serializableCheck: false
+ }),
});
...