I’m new to Redux (not React-Native) and The most straightforward way I found to use Redux is to use it with the createSlice
function.
Here is the slice –
import AsyncStorage from "@react-native-async-storage/async-storage";
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
isLoggedIn: false,
cart: null
}
const Slice = createSlice({
name: 'userAuth',
initialState,
reducers: {
setLogin: (state, action) => {
state.isLoggedIn = action.payload.isLoggedIn;
AsyncStorage.setItem("isLoggedIn", JSON.stringify(state.isLoggedIn));
},
setLogout: (state) => {
state.isLoggedIn = false;
AsyncStorage.clear();
},
setCart: (state, action) => {
state.cart = action.payload.cart;
AsyncStorage.setItem("cart", JSON.stringify(action.payload.cart));
},
startUp: (state, action) => {
state.cart = action.payload.cart;
state.isLoggedIn = action.payload.isLoggedIn;
}
}
});
export const { setLogin, setLogout, setCart, startUp } = Slice.actions;
export const selectIsLoggedIn = (state) => state.userAuth.isLoggedIn;
export const selectCart = (state) => state.userAuth.cart;
export default Slice.reducer;
I’m using the useDispatch
hook for updating the state.
const dispatch = useDispatch();
dispatch(setCart({cart: cartObj}));
But it leads me to an error-
WARN Possible Unhandled Promise Rejection (id: 0):
TypeError: Attempted to assign to readonly property.
onChange
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:191470:48
generatorResume@[native code]
asyncGeneratorStep@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25072:26
_next@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25094:29
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25101:14
tryCallTwo@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:30613:9
doResolve@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:30777:25
Promise@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:30636:14
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25090:25
onChange@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:191487:33
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:191758:24
generatorResume@[native code]
asyncGeneratorStep@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25072:26
_next@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:25094:29
tryCallOne@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:30604:16
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:30705:27
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:31784:26
_callTimer@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:31684:17
_callReactNativeMicrotasksPass@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:31719:17
callReactNativeMicrotasks@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:31926:44
__callReactNativeMicrotasks@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:24002:46
http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:23781:45
__guard@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:23985:15
flushedQueue@http://192.168.0.100:19000/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false:23780:21
flushedQueue@[native code]
callFunctionReturnFlushedQueue@[native code]
I’m using Expo-CLI on Ubuntu 22.04.
Please tell me the right way to do this.
3
Answers
You will need to use Redux Persist to perform state management with Async Storage.
Check this out for further instructions.
https://blog.logrocket.com/use-redux-persist-react-native/
setting data into the asyncStorage is asynchronous.
Under no circonstances you should not run an asynchronous value into reducer(should 100% synchronus). instead move the asyncStorage code to your api request function,then set it into asyncStorage.
you need to wrap AsyncStorage functions with async/await