react native redux toolkit devtools - react-native

how can I add redux devtools with redux toolkit ?
import { configureStore, getDefaultMiddleware, compose } from '#reduxjs/toolkit';
import reducers from './reducers';
import createSagaMiddleware from 'redux-saga';
import saga from './saga';
const sagaMiddleware = createSagaMiddleware();
const store = configureStore({
reducer: reducers,
devTools: process.env.NODE_ENV !== 'production',
middleware: getDefaultMiddleware => getDefaultMiddleware({ thunk: false }).concat(sagaMiddleware)
});
sagaMiddleware.run(saga);
export default store;
..................................................

It's activated by default with configureStore() and you can access it with this tool. react-native-debugger

As the official documentation specify in the Simplifying Store Setup with configureStore​ section: https://redux-toolkit.js.org/usage/usage-guide#simplifying-store-setup-with-configurestore, you don't have to add anything else since it already does it for you.

Related

How to persist redux store in React Native with redux-persist

I am using react-native with redux-persist and I cannot seem to get my store to persist into async storage. According to the redux-persist github repo, this may have to do with AsyncStorage being removed from react-native, but I cannot seem to figure out what needs to be done to fix the issue.
When my app launches I see the actions persist/PERSIST and persist/REHYDRATE fire in my redux devtools, but nothing ever is stored in async storage.
I thought I had set up my file as the redux-persist docs explained but I imagine I am missing something. I'm fairly new to Redux as it is so I may just be confused on something basic.
My Redux.config.js file ...
import React from 'react';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux'
import thunk from 'redux-thunk';
import { initialState } from './initialState';
import { puppyReducer } from './reducers/puppies/puppyReducer';
import { uiReducer } from './reducers/ui/uiReducer';
import { userReducer } from './reducers/user/userReducer';
import { contentReducer } from './reducers/content/contentReducer';
import { persistStore, persistReducer, persistCombineReducers } from 'redux-persist';
import storage from 'redux-persist/lib/storage'
import logger from 'redux-logger';
import Navigation from './Navigation.config';
import { PersistGate } from 'redux-persist/integration/react';
const persistConfig = {
key: 'root',
storage: storage
}
const rootReducer = {
dogs: puppyReducer,
ui: uiReducer,
user: userReducer,
content: contentReducer
};
const reducer = persistCombineReducers(persistConfig, rootReducer);
const persistedReducer = persistReducer(persistConfig, reducer);
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(persistedReducer, initialState, composeEnhancers(applyMiddleware(thunk), applyMiddleware(logger)));
const persistor = persistStore(store);
// Wrap the redux State Provider around the Main Navigation Stack
function StateWrapper() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Navigation />
</PersistGate>
</Provider >
)
}
export default App = StateWrapper;
I expect that this should load my persisted state when the app launches, and continue to update that persisted state as my redux state changes. As it stands currently, my state is updating fine, but nothing is persisted. There are no error messages showing.
I persist my redux store using AsyncStorage. Rather than using redux-persist's storage option, I have installed AsyncStorage from the #react-native-community. Just make sure that you link the dependency properly.
Then in my config.js file I import and use AsyncStorage as follows.
import AsyncStorage from '#react-native-community/async-storage';
const config = {
key: 'primary',
keyPrefix: '', // the redux-persist default `persist:` doesn't work with some file systems
storage: AsyncStorage,
};
Your issue could also be related to the keyPrefix try setting it to some value other than the default.
Try the following:
const reducer = persistCombineReducers(persistConfig, rootReducer);
const persistedReducer = persistReducer(persistConfig, reducer rootReducer);
This works for me:
//...
import {combineReducers} from 'redux';
import {persistReducer} from 'redux-persist';
const persistConfig = {
key: 'root',
storage: storage
}
const rootReducer = {
dogs: puppyReducer,
ui: uiReducer,
user: userReducer,
content: contentReducer
};
const persistedReducer = persistReducer(
persistConfig,
combineReducers(rootReducers)
);
//...

TypeError:undefined is not a function(evaluating 'store.getState()')

I have worked on react 16.6.3 with redux for passing parameters within components and send file data to backend.
I added reducers.js,actions.js,store.js and added those to my components but it generate error undefined is not a function(evaluating 'store.getState()').So please help me to solve this error. Thank you for advanced to all.
i changed the react version to and reinstall react-redux.
React store.getState is not a function i tried this suggestions also. It couldn't work.
reducers/index.js
let initialStateMarker = {
markers : []
}
const farmLocReducer=(state = initialStateMarker , action) => {
switch (action.type) {
case ADD_FARM_LOC:
state = Object.assign({}, state, {
farmIndex: action.farmIndex
});
return state;
default:
return state;
}
;
}
// this.index.farmLocReducer.farmLocReducer
const rootReducer = combineReducers({
farmLocReducer: farmLocReducer,
})
export default rootReducer;
store/index.js
import {createStore, applyMiddleware} from 'redux';
import {createContext} from "react";
import thunk from 'redux-thunk';
import rootReducer from '../reducers'; //Import the reducer
const store = createContext(createStore(rootReducer, applyMiddleware(thunk)));
export default store;

Apollo with redux-persist

I integrated react-apollo for fetching data from my GraphQL server into my react native application. I use redux-perist for persisting and rehydrating the redux store.
But I don't know how to rehydrate my apollo state.
Anyone know how I can do that?
Thanks
You can use the autoRehydrate feature of redux-persist. It will asyncronously run an action with type REHYDRATE that will rehydrate all stores unless you blacklist them.
If you try to execute a query that was previously executed, Apollo will check your Redux store first and you should see an APOLLO_QUERY_RESULT_CLIENT action execute (meaning it's returning from the client store instead of querying the server). You can modify the fetchPolicy to specify how the query gets its data (network only, cache first, etc.)
Here's a basic setup:
import React, { Component } from 'react';
import { ApolloProvider } from 'react-apollo';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { persistStore, autoRehydrate } from 'redux-persist';
import { AsyncStorage } from 'react-native';
const networkInterface = createNetworkInterface({ uri: 'http://localhost:8080/graphql' });
export const client = new ApolloClient({
networkInterface: networkInterface,
});
const store = createStore(
combineReducers({
apollo: client.reducer(),
}),
{}, // initial state
compose(
applyMiddleware(client.middleware()),
autoRehydrate(),
),
);
// persistent storage
persistStore(store, {
storage: AsyncStorage, // or whatever storage you want
});
export default class App extends Component {
render() {
return (
<ApolloProvider store={store} client={client}>
<YourApp />
</ApolloProvider>
);
}
}

Cannot connect react native app w/ remote redux devtools

I cannot connect my react-native app using redux to redux-devtools-extension through remote-redux-devtools.
I am using android device connected by USB on macOSX Sierra.
// configureStore.js
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from 'remote-redux-devtools';
import thunk from "redux-thunk";
import rootReducer from "./reducers";
const composeEnhancers = composeWithDevTools({ realtime: true });
export default function configureStore(initialState) {
const store = createStore(
rootReducer,
initialState,
composeEnhancers(
applyMiddleware(thunk),
)
);
if (module.hot) {
// Enable hot module replacement for reducers
module.hot.accept(() => {
const nextRootReducer = require('./reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
};
Redux is correctly configured into the app, w/ a simple button action to update redux state.
But it cannot found any store.
What am I missing ?
Try using this instead:
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

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
+ }),
});
...