My authSlice.js
import { createSlice } from "#reduxjs/toolkit"
const authSlice = createSlice({
name: 'auth',
initialState: {
userToken: 1
},
reducers: {
login: (state, action) => {
if (state.userToken === 0) {
state.userToken === 1
} else if (state.userToken === 1) {
state.userToken === 0
console.warn(state.userToken)
}
},
})
I am showing this in signin.js
const reduxtoken=useSelector((state)=>state.auth.userToken)
<Text style={styles.textDesign}>{reduxtoken}</Text>
The initial state i can see on screen as 1.imported dispatch assigned usedispatch.
const OnSignInPressed = async () => {
dispatch(login())
}
But the state remains the same and initial state value 1 on screen is remaining same as before state is not changing.
store.js
import { configureStore } from '#reduxjs/toolkit'
import { setupListeners } from '#reduxjs/toolkit/query'
import { userAuthApi } from '../services/userAuthApi'
import cartSlice from './cart-slice'
import authSlice from './auth-slice'
export const store = configureStore({
reducer: {
[userAuthApi.reducerPath]: userAuthApi.reducer,
cart: cartSlice.reducer,
auth: authSlice.reducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
immutableCheck: false
}).concat(userAuthApi.middleware)
})
setupListeners(store.dispatch)
Related
I use redux-persist in my Next js project. The status is saved in localStorage when the store is changed, but it is reset when the page is changed. What could be the problem? One of the reduser. I'm not sure, but maybe this problem is caused by SSR
import { createSlice, PayloadAction } from "#reduxjs/toolkit"
import { HYDRATE } from "next-redux-wrapper";
import { searchStateType } from "../../models/reduserModels/reduserModels";
const initialState: searchStateType = {
dataBar:
{
location: '',
date: {
from: undefined,
to: undefined
},
number: {
adults: 1,
child: 0,
rooms: 1
}
}
}
const searchDataSlice = createSlice({
name: 'search',
initialState,
reducers: {
searchbar: (state, action: PayloadAction<searchStateType>) => {
state.dataBar = { ...action.payload.dataBar }
}
},
extraReducers: {
[HYDRATE]: (state, action) => {
return {
...state,
...action.payload.search
}
},
}
})
export const { searchbar } = searchDataSlice.actions
export default searchDataSlice.reducer
store
const makeStore = () => {
const isServer = typeof window === "undefined";
const rootReduser = combineReducers({
search: searchDataReduser,
userData: userDataReduser,
regions: regionsIdReduser,
loading: visibleLoadingReduser,
hotelsRegion: hotelsRegionReduser,
hotelsId: hotelsIdReduser,
room: roomBookingReduser,
webRoom: webRoomBookingReduser,
bookingRoomData: bookingRoomsUserDataReduser,
});
if (isServer) {
const store = configureStore({
reducer: rootReduser,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: false,
serializableCheck: false,
}),
});
return store;
} else {
const persistConfig = {
key: "nextjs",
storage,
whitelist: ['search']
};
const persistedReducer = persistReducer(persistConfig, rootReduser);
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: false,
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
});
(store as any).__persistor = persistStore(store)
return store;
}
};
export const store = makeStore()
export type RootStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<RootStore['getState']>;
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action>;
export type AppDispatch = typeof store.dispatch
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export const wrapper = createWrapper<RootStore>(makeStore);
please help me solve this problem
const searchDataSlice = createSlice({
name: 'search',
initialState,
reducers: {
searchbar: (state, action: PayloadAction<searchStateType>) => {
state.dataBar = { ...action.payload.dataBar }
}
},
extraReducers: {
[HYDRATE]: (state, action) => {
let search = { ...action.payload.search };
delete search.PERSISTED_FIELD
return {
...state,
...search
}
},
}
})
im new in using redux and tried to use it with the help of online tutorials. nut im seeing this error:
Server Error TypeError: (0 , _react.createContext) is not a function
This error happened while generating the page. Any console logs will be displayed in the terminal window.
im providing my codes bellow:
authSlice.js file:
import { createSlice } from "#reduxjs/toolkit";
import { HYDRATE } from "next-redux-wrapper";
const initialState = {
authState: false,
userInfo: {},
authToken: ""
}
export const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
setAuthState(state, action) {
state.authState = action.payload
}
, setUserInfo(state, action) {
state.userInfo = action.payload
},
setToken(state, action) {
state.authToken = action.payload
},
setAuth(state, action) {
state.authState = action.payload.authState;
state.userInfo = action.payload.userInfo;
state.authToken = action.payload.authToken;
}
},
extraReducers: {
[HYDRATE]: (state, action) => {
return {
...state,
...action.payload.auth
}
}
}
})
export const { setAuthState, setUserInfo, setToken, setAuth } = authSlice.actions
export const selectAuthState = (state) => state.auth.authState;
export const selectAuthToken = (state) => state.auth.authToken;
export const selectUserInfo = (state) => state.auth.userInfo;
export default authSlice.reducer
store.js codes:
import { configureStore, ThunkAction, Action } from "#reduxjs/toolkit";
import { authSlice } from "./authSlice";
import { createWrapper } from "next-redux-wrapper";
const makeStore = () =>
configureStore({
reducer: {
[authSlice.name]: authSlice.reducer,
},
devTools: true,
});
const store = makeStore()
export default store
components where i tried to use redux:
import { useRouter } from "next/navigation";
import { useDispatch, useSelector } from "react-redux";
import {
selectAuthState,
selectAuthToken,
selectUserInfo,
setAuthState,
setUserInfo,
} from "#/data/authSlice";
function Sidebar() {
const router = useRouter();
const dispatch = useDispatch();
const authState = useSelector(selectAuthState);
const authToken = useSelector(selectAuthToken)
const userInfo = useState(selectUserInfo)
useEffect(() => {
if (!authState) {
router.push("/")
}
}, [router.asPath]);
// rest of the codes
import axios from "axiosConfig";
import { useDispatch, useSelector } from "react-redux";
import {
selectAuthState,
selectAuthToken,
setAuthState,
setUserInfo,
} from "#/data/authSlice";
// toastify
// import { toast } from 'react-toastify';
// import 'react-toastify/dist/ReactToastify.css';
// const notify = (text) => {
// toast.success(text , {position: toast.POSITION.BOTTOM_RIGHT})
// }
const LoginPage = () => {
const router = useRouter();
const dispatch = useDispatch();
const authState = useSelector(selectAuthState);
useEffect(() => {
const token = authState;
if (token) {
router.push("/Dashboard");
} else {
}
}, [router.asPath]);
// rest of the codes
i tried to reinstall redux and react-redux but didnt helped.
also tried Remove the node_modules
Remove package-lock.json
npm install again.
but nothing happend.
FYI: Everything is working fine and all the flows are working as expected but logs are confusing.
I am using Redux ToolKit for managing redux state & using Next Redux Wrapper for Server Side rendering and caching queries.
CartSlice.js
import { createSlice } from '#reduxjs/toolkit';
export const cartSlice = createSlice({
name: 'cart',
initialState: { data: [] },
reducers: {
addToCart: (state, action) => {
const itemInCart = state.data.find((item) => item.id === action.payload.id);
if (itemInCart) {
itemInCart.quantity += action.payload.quantity;
} else {
state.data.push({ ...action.payload });
}
}
},
});
export const cartReducer = cartSlice.reducer;
export const { addToCart } = cartSlice.actions;
ServiceApi.js
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'
export const serviceApi = createApi({
reducerPath: 'serviceApi',
baseQuery: fetchBaseQuery({ baseUrl: '<base-url>' }),
extractRehydrationInfo(action, { reducerPath }) {
if (action.type === HYDRATE) {
return action.payload[reducerPath]
}
},
endpoints: (builder) => ({
getItemById: builder.query({ query: (id) => `id/${id}` }),
getItems: builder.query({ query: () => `/` }),
}),
})
export const { getRunningQueriesThunk } = serviceApi.util
export const { useGetItemByIdQuery, useGetItemsQuery } = serviceApi
export const { getItemById, getItems } = serviceApi.endpoints;
store.js
import { configureStore } from '#reduxjs/toolkit'
import { serviceApi } from './serviceApi'
import { createWrapper } from "next-redux-wrapper";
import { cartSlice } from "./cartSlice";
export const store = configureStore({
reducer: {
[cartSlice.name]: cartSlice.reducer,
[serviceApi.reducerPath]: serviceApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(serviceApi.middleware),
})
const makeStore = () => store
export const wrapper = createWrapper(makeStore, {debug: true});
Using getServerSideProps
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async (context) => {
const { id } = context.query;
store.dispatch(serviceApi.endpoints.getItemById.initiate(parseInt(id)));
await Promise.all(store.dispatch(serviceApi.util.getRunningQueriesThunk()));
return {
props: {},
};
}
);
And using wrappedStore
const { store, props } = wrapper.useWrappedStore(pageProps);
On the UI flows everything is working as expected and i am able to add items in the cart and i can see the store state is getting updated by looking the UI.
But the logs from next redux wrapper is confusing:
I made two reducers(user, post) and needed to save them so I used redux-persist.
It doesn't work well. because once I dispatch user action then it also stored in post as well.
so I printed the state on the console.
There are postReducer, userReducer in post, and postReducer, userReducer in user.
I'm concerned that data is always stored twice and it looks dirty.
and below are my two reducer codes.
import { createSlice } from '#reduxjs/toolkit';
const initialStateValue = {accessToken: "", expiryTime: "", role: "", id: ""};
const userSlice = createSlice({
name: "user",
initialState: { value: initialStateValue},
reducers:{
login: (state, action) => {
state.userReducer.value = action.payload
},
logout: (state) => {
state.value = initialStateValue;
}
},
})
export const { login, logout } = userSlice.actions;
export default userSlice.reducer;
//
import { createSlice } from "#reduxjs/toolkit";
const initialStateValue = {category: "", title: "", content: ""};
const postSilce = createSlice({
name: "post",
initialState: { value: initialStateValue},
reducers: {
savePost: (state, action) => {
state.value = action.payload
}
},
})
export const { savePost } = postSilce.actions;
export default postSilce.reducer;
and below is my store.js
import React from 'react';
import { configureStore, getDefaultMiddleware } from "#reduxjs/toolkit";
import userReducer from "./userReducer";
import postReducer from "./postReducer";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
const persistConfig = {
key: "root",
storage,
};
const userPersistedReducer = persistReducer(persistConfig, userReducer);
const postPersistedReducer = persistReducer(persistConfig, postReducer);
export default configureStore({
reducer: {
user: userPersistedReducer,
post: postPersistedReducer,
},
middleware: getDefaultMiddleware({
serializableCheck: false,
}),
})
Error while dispatching an action!
React Hook useEffect has a missing dependency: 'dispatch'. Either include it or remove the dependency array react-hooks/exhausCompiled with warnings.
App.js :-
function App() {
const user = null;
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(userAuth => {
if (userAuth) {
dispatch(login({
uid: userAuth.uid,
email: userAuth.email
}));
} else {
dispatch(logout);
}
})
return unsubscribe;
}, []);
userSlice.js :-
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
},
reducers: {
login: (state, action) => {
state.user = action.payload;
}
},
logout: (state) => {
state.user = null;
}
});
export const { login, logout } = userSlice.actions;
store.js :-
import { configureStore } from '#reduxjs/toolkit';
import userReducer from '../features/userSlice';
export const store = configureStore({
reducer: {
user: userReducer,
},
});