I have an authReducer with and the User state.
I also have a generalReducer with state relating to error notification message and loading true/false.
How do I, when loading the login or another task in a seperate reducer, modify or make a global loading state variable from one reducer that is relating to another reducer?
generalReducer.js:
let defaultState = {
loading: false,
error: null,
notification: false,
};
export default function generalReducer(state = defaultState, action){
switch(action.type){
case loading:
return {
...state,
loading: action.payload.isLoading,
};
default:
return state;
}
authReducer.js
let defaultState = {
user: {
displayName: null,
email: null,
photoUrl: null,
isAnonymous: null,
phone: null,
}
};
export default function authReducer(state = defaultState, action){
switch(action.type){
case LOGIN_BEGIN:
case LOGOUT_BEGIN:
return {
...state,
};
case LOGIN_FAILURE:
case LOGOUT_FAILURE:
return {
...state,
};
case LOGIN_SUCCESS:
return {
...state,
user: action.payload.user
};
default:
return state;
}
}
In authReducer.js i want to be able to set the loading or error state in generalReducer to correspond to the error or loading state required. How?
You need to import authActionTypes from authActions and update the reducer in generalReducer.js
generalReducer.js:
import {
LOGIN_BEGIN,
LOGOUT_BEGIN,
LOGIN_FAILURE,
LOGOUT_FAILURE,
LOGIN_SUCCESS,
} from './authActions;
let defaultState = {
loading: false,
error: null,
notification: false,
};
export default function generalReducer(state = defaultState, action){
switch(action.type){
case loading:
return {
...state,
loading: action.payload.isLoading,
};
case LOGIN_BEGIN:
case LOGOUT_BEGIN: {
return {
...state,
loading: true,
error: null,
}
}
case LOGIN_FAILURE:
case LOGOUT_FAILURE: {
return {
...state,
loading: false,
error: 'Set Your Error Here',
}
}
case LOGIN_SUCCESS: {
return {
...state,
loading: false,
error: null,
}
}
default:
return state;
}
Hope this helps.
Related
I am trying to deploy the following source on Azure App Service via github connection but following errors are stopping the build but in my local linux box its working fine without any warning.
Error:
src/context/alert/alertReducer.js
Line 3:1: Assign arrow function to a variable before exporting as module default import/no-anonymous-default-export
src/context/github/githubReducer.js
Line 10:1: Assign arrow function to a variable before exporting as module default import/no-anonymous-default-export
alertReducer.js
import { SET_ALERT, REMOVE_ALERT } from "../types";
export default (state, action) => {
switch (action.type) {
case SET_ALERT:
return action.payload;
case REMOVE_ALERT:
return null;
default:
return state;
}
};
githubReducer.js
// Importing types
import {
SEARCH_USERS,
SET_LOADING,
CLEAR_USERS,
GET_USER,
GET_REPOS,
} from "../types";
export default (state, action) => {
switch (action.type) {
case GET_USER:
return {
...state,
user: action.payload,
loading: false,
};
case GET_REPOS:
return {
...state,
repos: action.payload,
loading: false,
};
case SEARCH_USERS:
return {
...state,
users: action.payload,
loading: false,
};
case CLEAR_USERS:
return {
...state,
users: [],
loading: false,
};
case SET_LOADING:
return {
...state,
loading: true,
};
default:
return state;
}
};
Different environments use different JS engines.
Some might not allow you to export unnamed functions. Try this.
const reducer (state, action) => {
switch (action.type) {
case SET_ALERT:
return action.payload;
case REMOVE_ALERT:
return null;
default:
return state;
}
};
export default reducer
Any idea why my reducer is acting on action.type based on its position in the switch statement?
I spent a lot of time debugging and then realized it was actually the position in the switch statement that is causing the problem.
import {
FETCH_PRODUCTS_BEGIN,
FETCH_PRODUCTS_SUCCESS,
FETCH_PRODUCTS_ERROR,
CREATE_PRODUCT,
UPDATE_PRODUCT,
DELETE_PRODUCT,
} from "./inventoryTypes";
const initialState = {
loading: false,
products: [],
error: "",
};
const userInventoryReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_PRODUCTS_BEGIN:
return {
...state,
loading: true,
};
case FETCH_PRODUCTS_SUCCESS:
return {
loading: false,
products: action.payload,
error: "",
};
case FETCH_PRODUCTS_ERROR:
return {
loading: false,
products: [],
error: action.payload,
};
case DELETE_PRODUCT:
return {
...state,
products: state.products.filter(
(product) => product._id !== action.payload
),
};
case CREATE_PRODUCT:
console.log("your calling create!");
return {...state}
case UPDATE_PRODUCT:
console.log("calling update");
return { ...state };
default:
return state;
}
};
Check the values inside your "./inventoryTypes" file' maybe there are duplications of the same actions.
This is resolved. The value for my CREATE_PRODUCT, UPDATE_PRODUCT inside "./inventoryTypes" is the same!
I would like to give more flexibility to my reducer without adding different initalstates and
cases.
I try to explain:
import {
FETCH_DB,
FETCH_CAT,
} from "../types"
// put a variable here:
const initalState = {
db: [],
categories: [], // create a dynamic state i.e. categories.VARIABLE
}
export default (state = initalState, action) => {
switch (action.type) {
case FETCH_DB:
return {
...state,
db: action.payload,
current: null,
loading: false,
}
case FETCH_CAT:
VARIABLE HERE
return {
...state,
categories[VARIABLE]: action.payload, // syntax with [] doesn't work
loading: false,
}
default:
return state
}
}
My aim is to pass a variable through out a component so I can have categories.VAR as many as I want.
Does someone know if is possible?
Thanks!
I guess it may be your solution 🙂
case FETCH_CAT:
const newState = {
...state,
loading: false
}
newState.categories[variable] = action.payload
return newState
Do
case FETCH_CAT:
return {
...state,
categories: {
...state.categories,
[variable]: action.payload
},
loading: false
}
I am trying to do an API call through reducer.My code is working fine here but the problem is all the actions, reducers are inside same file. So I tried to separate the reducer and actions in different file, but it is not working. I have debugged by putting some console.log but it is not helping me. Can anyone tell me how to fix it? I am providing my code snippet and sandbox below.
https://codesandbox.io/s/redux-async-actions-os6nu
import {
SELECT_CHANNEL,
REQUEST_POSTS,
RECEIVE_POSTS,
DISPLAY_ALERT
} from "../actions";
//const reducer = (state = {}, action) => {
const fetchReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_DATA_START:
return {
...state,
fetching: true,
fetchingMessage: "fetch data start"
};
case RECEIVED_DATA:
return {
...state,
fetching: false,
fetched: true,
data: action.payload,
fetchingMessage: "received data"
};
case FETCH_DATA_ERROR:
return {
...state,
fetching: false,
error: action.payload,
fetchingMessage: "fetch data error"
};
default:
return state;
}
};
export default fetchReducer;
You need to initialize your state in the main reducer file as well as use the same action name across all your application. I have also used mapStateToProps and mapDispatchToProps methods to make it easy and simple to use redux with react (https://redux.js.org/basics/usage-with-react).
Reducer file
import { combineReducers } from "redux";
import { REQUEST_POSTS, RECEIVE_POSTS } from "../actions";
const initialState = {
fetching: false,
fetched: false,
data: [],
error: null,
fetchingMessage: ""
};
const fetchReducer = (state = initialState, action) => {
switch (action.type) {
case REQUEST_POSTS:
return {
...state,
fetching: true,
fetchingMessage: "fetch data start"
};
case RECEIVE_POSTS:
return {
...state,
fetching: false,
fetched: true,
data: action.payload,
fetchingMessage: "received data"
};
case "FETCH_DATA_ERROR":
return {
...state,
fetching: false,
error: action.payload,
fetchingMessage: "fetch data error"
};
default:
return state;
}
};
export default combineReducers({ posts: fetchReducer });
App.js
const mapStateToProps = state => {
return {
data: state.posts
};
};
const mapDispatchToProps = dispatch => {
return {
onFetch: () => {
dispatch(requestPosts);
},
onFetchSuccess: data => {
dispatch(receivedPosts(data));
}
// onFetchError: () => {
// // dispatch()
// }
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
Here is the working demo link forked from your CodeSandbox (https://codesandbox.io/s/redux-async-actions-436qu). Let me know if you do not understand anything.
When I try to call any other action in redux it is setting one part of the state to it's initialState.
My root reducer looks like this
const rootReducer = combineReducers({
credentials: combineReducers({
cred,
user,
partner,
merchant,
bank,
error,
auth,
}),
preCredentials,
theme,
});
the part of the state that is being cleared is theme.
action dispatched
state diff
Why this actions that have anything to do with theme reducer can change its state.
Theme reducer
function theme(state = { ...INITIAL_THEME }, action) {
switch (action.type) {
case LOADING_THEME:
return {
...state,
isLoading: true,
};
case SAVE_THEME:
return {
...action.theme,
error: {
status: null,
message: '',
},
isLoading: false,
};
case CLEAR_THEME:
return INITIAL_THEME;
default:
return INITIAL_THEME;
}
}
reducer of dispatched action
function preCredentials(state = { ...INITIAL_STATE }, action) {
switch (action.type) {
case SAVE_USERNAME:
return { ...state,
user: { ...state.user,
fullName: action.fullName,
},
};
default:
return state;
}
}
function theme(state = { ...INITIAL_THEME }, action) {
switch (action.type) {
case LOADING_THEME:
return {
...state,
isLoading: true,
};
case SAVE_THEME:
return {
...state,
...action.theme,
error: {
status: null,
message: '',
},
isLoading: false,
};
case CLEAR_THEME:
return INITIAL_THEME;
default:
return state;
}
}
return state instead of initial state