React Native with Redux-Persist , PersistGate inifinite loading - javascript

I'm working on an app in react native and must work with Redux-Persist. I have the store configuration set up, no errors occur but the rehydration never happens and the persistentGate is infinitely in the loading state.
Here is my store.js
import { createStore, combineReducers } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import entriesReducer from './reducers/entries';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const rootReducer = combineReducers({
entries : entriesReducer
});
const persistConfig = {
key: 'root',
storage: storage,
stateReconciler: autoMergeLevel2 // see "Merge Process" section for details.
};
const pr = persistReducer(persistConfig, rootReducer);
const configureStore = () => {
const store = createStore(rootReducer);
const persistor = persistStore(store);
return { persistor, store };
};
export default configureStore;
And my index.js
import React from 'react';
import { AppRegistry } from 'react-native';
import {Provider} from 'react-redux';
import App from './App';
import configureStore from './src/store/configureStore';
import { PersistGate } from 'redux-persist/lib/integration/react';
const store = configureStore();
const RNRedux = () => (
<Provider store={store.store}>
<PersistGate loading={<App />} persistor={store.persistor}>
<App/>
</PersistGate>
</Provider>
);
AppRegistry.registerComponent('PTM', () => RNRedux);
Any help will be very much appreciated, I've been trying to set this up for days now with no success. Previously I would have to deal with errors but now I don't see any and it still refuses to work, I simply don't know where to look for the fault.
Edit:
App.js file
import React from 'react';
import { View, Text, Button, StatusBar } from 'react-native';
import { StackNavigator } from 'react-navigation';
import {connect} from 'react-redux';
import NavBar from './src/components/NavBar/NavBar';
import DayPicker from './src/components/DayPicker/DayPicker';
import TotalTime from './src/components/TotalTime/TotalTime';
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';
import EntriesList from './src/components/EntriesList/EntriesList';
var x = null;
const RootStack = StackNavigator(
{
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
And my HomeScreen is using this:
const mapStateToProps = state => {
return {
data : state.entries.data,
entriesPerDay : state.entries.entriesPerDay,
pickedDate : state.entries.pickedDate,
total: state.entries.total
};
};
const mapDispatchToProps = dispatch => {
return {
onPickDate: (day) => dispatch(pickDay(day)),
onDataSet: (data) => dispatch(setData(data))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen);

Related

React Redux -> TypeError: Object(...) is not a function

So I'm learning react and I've split my code into seperate files which are, as follows ->ReduxDemo.js/reducers.js/store.js/actions.js
Here is their content:
ReduxDemo.js:
import React from 'react'
import {useSelector} from 'react-redux'
function ReduxDemo(){
const cakeAmount = useSelector(state=>state.cakeCount)
return(
<div>
<div>
<h1>Amount of cakes - {cakeAmount}</h1>
</div>
</div>)
}
export default ReduxDemo;
reducers.js:
import {combineReducers} from 'redux'
const cakeState=
{
cakeCount: 10,
}
const iceCreamState=
{
iceCreamCount: 20
}
const cakeReducer=(state={cakeState},action)=>
{
switch(action.type)
{
case 'buyCake':
return{
...state,
cakeCount: state.cakeCount -1
}
default:
return state
}
}
const iceCreamReducer=(state=iceCreamState, action)=>
{
switch(action.type)
{
case 'buyIceCream':
return{
...state,
iceCreamCount: state.iceCreamCount-1
}
default:
return state;
}
}
const reducers = combineReducers(
{
cake: cakeReducer,
iceCream: iceCreamReducer
})
export default reducers;
store.js:
import reducers from './reducers'
import {createStore} from 'react'
const store = createStore(reducers)
store.subscribe(()=>
{
console.log('store changed:', store.getState())
})
export default store;
actions.js:
import store from './store'
export const buyCake=()=>
{
store.dispatch({type: 'buyCake'})
}
App.js:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import ReduxDemo from './ReduxDemo'
import {Provider} from 'react-redux'
import store from './store'
function App() {
return (
<div>
<Provider store={store}>
<ReduxDemo></ReduxDemo>
</Provider>
</div>
);
}
export default App;
for some obscure to me reason I get "TypeError: Object(...) is not a function", that is supposedly located at this line in store.js -> const store = createStore(reducers) Why is that and how can I fix it?
createStore is not a function offered by React. You need to import it from Redux:
// store.js
import { createStore } from 'redux'

Loading Screen using PersistGate doesn't render

I'm using redux-persist and I'm trying to render a screen passing it to the loading prop of PersistGate.
I did some research and I found that I should dispatch REHYDRATE to the reducer but that doesn't work either.
Maybe I'm not configuring my reducers well?
I would also like to be able to set the loading prop to null to avoid the flash screen before the App renders, but the result is the same as passing it a component to render.
This is my code of index.js
import App from './App';
import React from 'react';
import { Provider } from 'react-redux';
import { AppRegistry } from 'react-native';
import { PersistGate } from 'redux-persist/integration/react';
import { SplashScreen } from './src/screens/SplashScreen';
import configureStore from './src/store/configureStore';
const store = configureStore();
const persistor = configureStore();
const RNRedux = () => (
<Provider store={store}>
<PersistGate loading={<SplashScreen/>} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
componentDidMount = () => {
this.persistor.dispatch({ type: REHYDRATE });
};
AppRegistry.registerComponent('Sharryapp', () => RNRedux);
And that's my configureStore file:
import { createStore, combineReducers, applyMiddleware} from 'redux';
import ServerReducer from './reducers/ServerReducer';
import InviteReducer from './reducers/InviteReducer';
import { persistStore, persistReducer } from 'redux-persist';
import thunk from 'redux-thunk';
import storage from 'redux-persist/lib/storage';
const rootReducer = combineReducers({
server: ServerReducer,
invite: InviteReducer,
});
const persistConfig = {
key: 'root',
debug: true,
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer,applyMiddleware(thunk));
const persistor = persistStore(store);
export default configureStore = () => {
return ( store, persistor );
};
I am not sure why you wrap your store and persistor in a configureStore function.
Instead import both separately:
export const store = createStore(persistedReducer,applyMiddleware(thunk));
export const persistor = persistStore(store);
And import them in your desired file:
import {store, persistor} from './src/store/configureStore';
I have also noticed that your createStore call is false, since enhancers are passed as the third parameter. Change it to:
const store = createStore(persistedReducer, undefined, applyMiddleware(thunk));
That should do it.
Also you do not need to dispatch a rehydrate action as it happens automatically on app start.

React-native-Redux: could not find stored in either the context or props of connect(componentName)

I'm getting below error even i had defined store for root component.
click to enlarge image
Not sure why im getting this error even after defining store.
index.js (rootpage)
import React, {Component} from 'react';
import {initStore} from './redux/store';
import {Provider} from 'react-redux';
import App from './App.container';
const store = initStore();
class BuddApp extends Component {
render () {
return (
<Provider store={store}>
<App />
</Provider>
);
}
}
export default BuddApp;
This is app.container.js which is inside app.
app/app.container.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import Router from './routes';
import Proptypes from 'prop-types';
import {addNavigationHelpers} from 'react-navigation';
class App extends Component {
render () {
const {dispatch, nav, userPreferences} = this.props;
console.log(this.props)
return (
<Router screenProps={userPreferences} navigation={addNavigationHelpers({dispatch, state: nav})}/>
</Provider>
);
}
}
App.propTypes = {
dispatch: Proptypes.func,
nav: Proptypes.object,
userPreferences: Proptypes.object
};
const mapStateToProps = ({nav, userPreferences}) => ({
nav,
userPreferences
});
const mapDispatchToProps = (dispatch) => ({
dispatch
});
export default connect(mapStateToProps, mapDispatchToProps)(App);
app/pages/login.page.js
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import Login from '../components/Login/Login.component';
import {NavigationActions} from 'react-navigation';
class LoginPage extends Component {
onLoginPress(){
console.log("fsdfds")
this.props.navigation.navigate('setupProfile')
}
render () {
const {state} = this.props;
return (
<Login onLoginPress={this.onLoginPress.bind(this)} />
);
}
}
LoginPage.propTypes = {
onLoginPress: PropTypes.func
};
const mapStateToProps = (state) => ({
state:state
});
const mapDispatchToProps = (dispatch) => ({
saveLoginDetails: dispatch(addProfile(f))
});
export default connect(mapStateToProps,mapDispatchToProps)(LoginPage);
This results in getting the above mentioned error. as you can see I am passing the store in the same manner as shown in the redux example.
Am i defined store in wrong file?
Try this way:
import { createStore, applyMiddleware } from "redux"
const store = createStore(
<<Your combined reducers comes here>>,
applyMiddleware(<<All your middleware comes here>>))

Using connect with react-redux and redux-persist

I am getting the following error on my react-redux & redux-persist setup:
The above error occurred in the component: in Connect(App) (created by
Route) in Route (created by withRouter(Connect(App))) in
withRouter(Connect(App)) in Router (created by BrowserRouter) in
BrowserRouter in PersistGate in Provider
I have it setup like this:
store.js
import {applyMiddleware, createStore} from 'redux';
import {persistStore,persistCombineReducers} from 'redux-persist';
import storage from 'redux-persist/es/storage' // default: localStorage if web, AsyncStorage if react-native
import { logger } from 'redux-logger';
import thunk from 'redux-thunk';
import promise from 'redux-promise-middleware';
import reducer from './reducers'
const middleware = applyMiddleware(promise(), thunk, logger);
const config = {
key: 'root',
storage,
};
const reducers = persistCombineReducers(config, {reducer});
export const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import {Provider} from 'react-redux';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import './css/app.css';
import App from './containers/App';
import { PersistGate } from 'redux-persist/es/integration/react'
import configureStore from './store';
const { persistor, store } = configureStore()
ReactDOM.render(
<Provider store={store} >
<PersistGate persistor={persistor}>
<BrowserRouter>
<App/>
</BrowserRouter>
</PersistGate>
</Provider>,
document.getElementById('root')
);
App.js
import React from 'react'
import { withRouter, Switch, Route } from 'react-router-dom'
import { connect } from 'react-redux'
...
#withRouter
#connect((store) => {
return {
isAuthenticated: store.auth.isAuthenticated,
};
})
export default class App extends React.Component {
render() {
...
}
}
UPDATE 1
Full console log
UPDATE 2
Is this the right way to declare the reducer? It works fine without redux-persist
authReducer.js
export default function reducer(state = {
isAuthenticated: false
}, action) {
...
}
UPDATE 3
REHYDRATE console log
UPDATE 4
index.js (in reducers folder)
import { combineReducers } from 'redux';
import user from './userReducer';
import auth from './authReducer';
export default combineReducers({
user,
auth
})
So the problem was that one should not use both combineReducers and persistCombineReducers in one go. Similar situation could be found here https://github.com/rt2zz/redux-persist/issues/516

Can't get React-redux to work with redux-persist

Hi I am trying to setup redux-persist with react-redux, but I cant get it to work. I get the following error:
TypeError: _store2.default is not a function [Learn More] index.js:12:29
How I have the setup right now:
store.js
import {applyMiddleware, createStore} from 'redux';
import {persistStore,persistCombineReducers} from 'redux-persist';
import storage from 'redux-persist/es/storage' // default: localStorage if web, AsyncStorage if react-native
import { logger } from 'redux-logger';
import thunk from 'redux-thunk';
import promise from 'redux-promise-middleware';
import reducer from './reducers'
const middleware = applyMiddleware(promise(), thunk, logger);
const config = {
key: 'root',
storage,
};
const reducers = persistCombineReducers(config, {reducer});
export const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import {Provider} from 'react-redux';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import './css/app.css';
import App from './containers/App';
import { PersistGate } from 'redux-persist/es/integration/react'
import configureStore from './store';
const { persistor, store } = configureStore()
ReactDOM.render(
<Provider store={store} >
<PersistGate persistor={persistor}>
<BrowserRouter>
<App/>
</BrowserRouter>
</PersistGate>
</Provider>,
document.getElementById('root')
);
UPDATE 1
Based on #azium's response now I get:
The above error occurred in the component:
in Connect(App) (created by Route)
in Route (created by withRouter(Connect(App)))
in withRouter(Connect(App))
in Router (created by BrowserRouter)
in BrowserRouter
in PersistGate
in Provider
When calling it like so from App.js:
#withRouter
#connect((store) => {
return {
isAuthenticated: store.auth.isAuthenticated,
};
})
If you want to use the default export you need to change:
export const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
to:
export default () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
or:
const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
export default configureStore;
or if you don't want to use default export change:
import configureStore from './store';
to:
import { configureStore } from './store';
So after a bit of thinkering and community help I managed to narrow down the issue to my reducer declaration. I was declaring reducer in index.js with combineReducers whilst redux-persist says it shouldn't be.
Final index.js code:
import user from './userReducer'
import auth from './authReducer'
export default ({
user, auth
})

Categories

Resources