Illegal constructor using useSelector from react-redux lib? - javascript

Why do I get this error?
TypeError: Illegal constructor
Beow is my store.js file:
import { configureStore, combineReducers } from '#reduxjs/toolkit'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import formReducer from './features/form/form'
import modalReducer from './features/modal-status/modal'
const persistConfig = {
key: 'root',
storage,
}
const rootReducer = combineReducers({
modal: modalReducer,
process: formReducer
})
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default function createStore() {
let store = configureStore({
reducer: persistedReducer,
devTools: true
})
let persistor = persistStore(store)
return { store, persistor }
}
Below is my form reducer code:
import { createSlice } from '#reduxjs/toolkit'
export const formSlice = createSlice({
name: 'process',
initialState: {
type: 'UNKNOWN',
isLogined: false,
username: null,
clientId: null,
avatarUri: null
},
reducers: {
process(state, action) {
if(action.payload.type == 'LOGIN') {
if('username' in action.payload && 'clientId' in action.payload && 'avatarUri' in action.payload) {
return {
...state,
type: 'LOGIN',
isLogined: action.payload.isLogined,
username: action.payload['username'],
clientId: action.payload['clientId'],
avatarUri: action.payload['avatarUri'],
}
}
} else {
return state
}
}
}
})
export const { process } = formSlice.actions
export default formSlice.reducer
And in react component I used useSelector hook like below:
const isLogin = useSelector(state => state.process.isLogined)

Related

The previous state received by the reducer has unexpected type of "array". Expected argument to be an object with the following keys:

I don't understand why the following error appears:
reducers\userReducer
import { createSlice } from "#reduxjs/toolkit";
export const userSlice = createSlice({
name: 'user',
initialState:{
currentUser: {},
isAuth: false
},
reducers: {
setUser(state, action) {
state.currentUser = action.payload;
state.isAuth = true
}
}
})
export const {setUser} = userSlice.actions
export default userSlice.reducer
It seems to me that the problem is in combineReducers, but I may be wrong
index.js
import {configureStore, combineReducers} from '#reduxjs/toolkit'
import {applyMiddleware} from 'redux'
import {composeWithDevTools } from 'redux-devtools-extension'
import thunk from "redux-thunk";
import {userSlice} from './userReducer';
const rootReducer = combineReducers({
user:userSlice.reducer
})
export const setupStore = () => {
return configureStore ({
reducer: rootReducer,
middleware: composeWithDevTools(applyMiddleware(thunk))
});
}

How to call reducer function of one slice to another slice

Slice One
/*eslint-disable*/
import { createAsyncThunk, createSlice, PayloadAction } from '#reduxjs/toolkit';
const initialState = { };
const patientSlice = createSlice({
name: 'Patient Slice',
initialState: initialState,
reducers: {
TestingOtherSliceCall: (state: any, { payload }: any) => {
alert('heelllo im from patient slice');
}
},
extraReducers: {
[GetInsurancePayersFilter.pending]: (state: any) => {
state.loadingInsurancePayersFilter = true;
},
[GetInsurancePayersFilter.fulfilled]: (state: any, { payload }: PayloadAction<TPayloadList>) => {
state.loadingInsurancePayersFilter = false;
state.getInsurancePayersFilter = payload;
},
[GetInsurancePayersFilter.rejected]: (state: any) => {
state.loadingInsurancePayersFilter = false;
},
}
});
export const { TestingOtherSliceCall patientSlice.actions;
export const patientReducer = patientSlice.reducer;
Slice Two
/*eslint-disable*/
import { createAsyncThunk, createSlice, PayloadAction } from '#reduxjs/toolkit';
import { TestingOtherSliceCall } from './patient';
const initialState = {};
insurance end ******** */
const userSlice = createSlice({
name: 'User Slice',
initialState: initialState,
reducers: {
DynamicTabAppend: (state: any, { payload }) => {
TestingOtherSliceCall(null);
},
},
extraReducers: {
}
});
export const { TestingOtherSliceCall userSlice.actions;
export const userReducer = userSlice.reducer;
Root Reducer
import { patientReducer } from './../slices/patient';
import { combineReducers } from '#reduxjs/toolkit';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import { createFilter } from 'redux-persist-transform-filter';
export const rootReducer = combineReducers({
user: userReducer,
patient: patientReducer,
});
export const persistConfig = {
key: 'root',
storage,
whitelist: ['auth', 'schedule'],
};
export const persistedReducer = persistReducer(persistConfig, rootReducer);
I tried calling from one slice reducer to another but function does'nt invoke.

Updating state, gives empty state in react redux toolkit

Am trying to make a login and add the return data to state, when I try to update state, it still gets empty state. I have added the code below, Please help me fix it. Am using RTK query to make the login mutation, and am new to this.
My AuthApi.js
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
import { api } from "./api";
export const authApi = createApi({
reducerPath: "authApi",
baseQuery: fetchBaseQuery({
baseUrl: api
}),
endpoints: (builder) => ({
loginUser: builder.mutation({
query: (body) => {
return {
url: "login",
method: "post",
body,
};
},
}),
registerUser: builder.mutation({
query: (body) => {
return {
url: "register",
method: "post",
body,
};
},
}),
}),
});
export const { useLoginUserMutation, useRegisterUserMutation } = authApi;
My userSlice.js
import { createSlice } from "#reduxjs/toolkit";
import { authApi } from "../../services/authApi";
const initialState = {
role: null,
accessToken: null,
userData: null
}
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
logout: (state) => {
state.currentUser = null;
state.errorMessage = ''
}
},
extraReducers: (builders) => {
builders.addMatcher(authApi.endpoints.loginUser.matchFulfilled, (state, action) => {
state.userData = action.payload.success.data
state.accessToken = action.payload.success.accessToken
state.role = action.payload.success.roles
})
}
})
export const { logout } = userSlice.actions
export const selectUser = (state) => state.user.accessToken
export default userSlice.reducer
my store.js
import { configureStore } from "#reduxjs/toolkit";
import { authApi } from "../services/authApi";
import userReducer from './slices/userSlice'
const store = configureStore({
reducer: {
[authApi.reducerPath]: authApi.reducer,
user: userReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(authApi.middleware),
});
export default store;
console.log(action.payload) in userSlice extraReducer gives me the data in console, but it is not updating the state.

Uncaught TypeError: Cannot read properties of undefined (reading 'user')

import { createSlice } from '#reduxjs/toolkit';
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
},
// The `reducers` field lets us define reducers and generate associated actions
reducers: {
login: (state, action) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
},
},
});
export const { login, logout } = userSlice.actions;
export const selectUser = (state) => state.user.user;
export default userSlice.reducer;
Error: userSlice.js:22 Uncaught TypeError: Cannot read properties of
undefined (reading 'user')
at selectUser (userSlice.js:22:1)
export const selectUser = (state) => state.user === null ? '' : state.user.user;
// or
export const selectUser = (state) => state.user === null ? {} : state.user.user;
you need to use configureStore and use useSelector to get the user
step1:
you can create new file named store or any name you want
import { configureStore } from "#reduxjs/toolkit";
import User from "./slices/userSlice";
const store = configureStore({
reducer: {
User: User,
},
});
export default store;
step2:
you need to add the provider in the index.js like this:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store/index";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
step3:
use useSelector to get the user from any place like this :
const user = useSelector((state) => state.User.user);
console.log(user);
Try declaring the initial state outside the createSlice function
import { createSlice } from '#reduxjs/toolkit';
const initialState = { user: null }
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
login: (state, action) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
},
},
});
export const { login, logout } = userSlice.actions;
export const selectUser = (state) => state.user.user;
export default userSlice.reducer;
Or simple just put an object in the place of initialState,
so something like
import { createSlice } from '#reduxjs/toolkit';
const initialState = { user: null }
export const userSlice = createSlice({
name: 'user',
//you put your initialState object here
{user : null},
reducers: {
login: (state, action) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
},
},
});
export const { login, logout } = userSlice.actions;
export const selectUser = (state) => state.user.user;
export default userSlice.reducer;

How to store local storage and regular data at the same time in a reducer ( redux-persist)?

I have store.js
import {configureStore, combineReducers} from "#reduxjs/toolkit"
import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import userData from "./userData";
import loadingStatus from "./loadingStatus";
const rootReducer = combineReducers({
data: userData,
});
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
})
export const persistor = persistStore(store);
export default store;
And some slicers :
loadingStatus.js
import {createSlice} from "#reduxjs/toolkit";
const loadingStatus = createSlice({
name: 'loaded',
initialState: {
loaded : false
},
reducers: {
setLoading(state, action) {
return { loaded: action.payload}
}
},
});
export const {setLoading} = loadingStatus.actions;
export default loadingStatus.reducer;
userData.js
import {createSlice} from "#reduxjs/toolkit";
const userData = createSlice({
name: 'data',
initialState: {
data : []
},
reducers: {
getData(state, action) {
return { data: action.payload}
}
},
});
export const {getData} = userData.actions;
export default userData.reducer;
The problem is that I only need to store one state in localStorage - userData (this works now), but I also have a loaded state that I don't need in local storage. How can I store local storage and deffault states at the same time?

Categories