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
}
Related
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!
This is probably a mistake on my part but I've noticed that in my Redux store, for every entity, there seems to be an outer object named x which in turn has a child with the same name, which then contains the data.
This is better explained with an example:
user reducer
const initialState = {
user: {},
}
const usersReducer = (state = initialState, action) => {
switch (action.type) {
case LOGIN_USER:
return {
...state,
user: action.payload,
loggedIn: true,
}
case REGISTER_USER:
return {
...state,
user: action.payload,
registered: true,
}
default:
return state
}
}
user object in state
As you can see, user has a user nested inside of it.. can this pattern be avoided somehow in the reducer?
You can change your script on
case LOGIN_USER:
return {
...state,
...action.payload,
loggedIn: true,
}
etc..
it's should help you
Below is the code of my reducer. whenever I am trying to update list array it says it is not iterable. Can anyone please tell me what mistake I am doing?
initialState = {
list: [],
taskAdded: false,
taskList: ""
}
export const task = (state = initialState, action) => {
switch (action.type) {
case types.ADD_TASK:
return {
...state,
taskList: action.payload,
taskAdded: true,
list: [...state.list, action.payload]
}
case types.CLEAR_ADD_TASK_STATE:
return {
...state,
taskList: "",
taskAdded: false
}
default:
return state
}
}
I have this git repo i created
https://github.com/markortiz905/emp-app
Ive been practicing reactjs and wanted to learn about redux-thunk,
at first kinda easy but I fall short on understanding how it works on routes as well.
My investigation led me to think that data fetched from server is not triggering update component due to routing ?
If anyone have time to take a look on my repo its just few files and codes simple fetch empmloyee and display on view
Heres my reducer.js snippet
const initStates = {
employees: [],
loading: true
};
function rootReducer(state = initStates, action) {
console.log(state.employees);
if (action.type == UPDATE_EMPLOYEES) {
state.employees = action.payload;
} else if (action.type == LOADING) {
state.loading = action.payload;
}
//means something happen bad
return state;
}
I just found out whats wrong, it seems that I am doing it wrong from the very start in my reducer script
This is wrong, I am updating employees from the const variable but const cant be updated right? once you’ve assigned a value to a variable using const, you can’t reassign it to a new value. source - https://tylermcginnis.com/var-let-const/
const initStates = {
employees: [],
loading: true
};
function rootReducer(state = initStates, action) {
console.log(state.employees);
if (action.type == UPDATE_EMPLOYEES) {
state.employees = action.payload;
} else if (action.type == LOADING) {
state.loading = action.payload;
}
//means something happen bad
return state;
}
I changed my reducer to return the new object instead.
function rootReducer(state = initStates, action) {
switch (action.type) {
case UPDATE_EMPLOYEES_STARTED:
return {
...state,
loading: true,
employees: null,
};
case UPDATE_EMPLOYEES:
return {
...state,
loading: false,
error: null,
employees: action.payload,
};
case UPDATE_EMPLOYEES_ENDED:
return {
...state,
loading: false,
employees: [...state.employees],
};
default:
return state;
}
}
I'm building a quite simple app using Redux and my reducers all look alike. It works, technically, but that's a lot of code duplication.
// The employees reducer
export default (state = initialState, action) => {
switch (action.type) {
case EMPLOYEES_REQUEST:
return [ ...state, { isFetching: true } ]
case EMPLOYEES_SUCCESS:
// DEBUG
console.log('Dispatching employees');
console.log(action.response);
// END DEBUG
// Return employees directly in the employees state
return { ...state, list: JSON.parse(action.response) };
case EMPLOYEES_FAILURE:
return [ ...state, { isFetching: false } ]
default:
return state
}
}
And
// The services reducer
export default (state = initialState, action) => {
switch (action.type) {
case SERVICES_REQUEST:
return [ ...state, { isFetching: true } ]
case SERVICES_SUCCESS:
// DEBUG
console.log('Dispatching services');
console.log(action.response);
// END DEBUG
// Return services directly in the services state
return { ...state, list: JSON.parse(action.response) };
case SERVICES_FAILURE:
return [ ...state, { isFetching: false } ]
default:
return state
}
}
Is there something I can to to use a generic reducer with different actions?
Thanks!
Reducer is just a function. You could always use a higher order function to make it.
const makeListReducer = (initial, prefix) => (state = initial, action) => {
switch(action.type) {
case `${prefix}_REQUEST`: return {...state, isFetching: true}
case `${prefix}_SUCCESS`: return {...state, isFetching: false, list: JSON.parse(action.response)}
case `${prefix}_FAILURE`: return {...state, isFetching: false, /*etc*/}
}
return state
}
// The employees reducer
export default makeListReducer(initialState, 'EMPLOYEES')