react-redux with redux thunk with Router - reactjs

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;
}
}

Related

Redux reducer state was not updating with previous state while using hooks

Hi currently i am creating a project using hooks with redux.
while every time i trigger a new request ...state was not maintaining the previous data.so please help upon this .
const initialState = {
isLoaded: false,
followData:{},
FollowerCountData:{}
}
export default function followReducer(state = initialState, action) {
switch (action.type) {
case allActions.FETCH_FOLLOW_DATA:
return action;
case allActions.RECIEVE_FOLLOW_DATA:
return {
...state,
followData: action.payload,
};
case allActions.FETCH_FOLLOWER_COUNT:
return action;
case allActions.RECIEVE_FOLLOWER_COUNT:
return {
...state,
FollowerCountData: action.payload,
};
default: return state;
}
}

Two Boolean states in the Init State of Reducer, One returns undefined

I've been working with redux for the last couple weeks and was incorporating it into my projects when I ran into this wall. Pretty common reducer for modals being rendered so i can animate them before unmounting them.
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
switch (action.type) {
case "modalInteraction":
return {
isModalOpen: action.payload
};
case "testModalInteraction":
return {
test: action.payload
};
default:
return state;
};
}
Sadly, the test property is still returning as undefined despite the fact that the other initial state in the same reducer can be called without a problem. I even removed all the testModalInteraction dispatches in the case that that somehow upset the datatype. I just can't spot the difference that keeps returning undefined.
When you return the new state, make sure to spread the initial state (...state) and then change whatever values you need to change.
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
switch (action.type) {
case "modalInteraction":
return {
...state,
isModalOpen: action.payload
};
case "testModalInteraction":
return {
...state,
test: action.payload
};
default:
return state;
};
}
If it is still undefined, make sure the payloads are defined for both actions.
For example, your modalInteraction action could look like
export const modalInteraction = (bool) => ({
type: "modalInteraction",
payload: bool
})
P.S., you can destructure the action object. This allows you to use "type" instead of "action.type" and "payload" instead of "action.payload".
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
const {type, payload} = action;
switch (type) {
case "modalInteraction":
return {
...state,
isModalOpen: payload
};
case "testModalInteraction":
return {
...state,
test: payload
};
default:
return state;
};
}

React Redux - Variable into initialstate and how to create CASE dynamically

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
}

Redux store not updating array instead throws an error state. List is not iterable

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
}
}

How to filter Redux actions?

Is it okay to add more info to an action so component specific reducers (and sagas/whatever side effect lib you're using) can filter them?
Example:
function reducerComponentA(state, action) {
switch (action.type) {
case START_FETCH:
return {
...state,
isLoading: true,
};
break;
case START_FETCH_SUCCESS:
return {
...state,
isLoading: false,
};
break;
}
return state;
}
and
function reducerComponentB(state, action) {
switch (action.type) {
case START_FETCH:
return {
...state,
isLoading: true,
};
break;
case START_FETCH_SUCCESS:
return {
...state,
isLoading: false,
};
break;
}
return state;
}
Notice how both reducers observes the same action and act on them (show a loading animation). Now if the screen/component that these reducers are related to are both in memory, the START_FETCH will cause to both of them to show the loading animation, maybe even overlapping (because it's global). Is filtering actions by screen/component a good solution?
Like this:
function reducerComponentA(state, action) {
if (action.currentScreen === 'ScreenA') {
switch (action.type) {
...
}
}
return state;
}
This seems to more of a problem on React Native, because if you're using a Navigator, there's a chance multiple screens will be loaded at the same time.
You can 'mount' reducer to the different slices of the state. To achieve this, you can add path to the action, and in the reducer, update corresponding slice of the state.
It can be similar to:
function reducer(state, action) {
if (action.type === '...') {
return _.set(_.deepClone(state), `${action.path}.isLoading`, false)
} else return state;
}
In other words, action determines which part of the state reducer will be operating with.
Note that this example above is extremely inefficient and only for demo purpose. Instead of cloning the state, some immutability helpers should be used: kolodny/immutability-helper, mweststrate/immer, other.
UPD
Imagine you have action and reducer for an input state:
const UPDATE_VALUE = 'UPDATE_VALUE';
const updateValue = (value) => ({ type: UPDATE_VALUE, value })
function reducer(state, action) {
if (action.type === UPDATE_VALUE) {
return { ...state, input: action.value }
} else return state;
}
And you want to use this action/reducer for many different inputs. The action can be supplied with
a property path that indicates which part or the state should be updated, and eventually which input
will receive new props:
const UPDATE_VALUE = 'UPDATE_VALUE';
const updateValue = (value, path) => ({ type: UPDATE_VALUE, value, path })
function reducer(state, action) {
if (action.type === UPDATE_VALUE) {
return { ...state, [action.path]: action.value }
} else return state;
}
This can be used then:
dispatch(updateValue(event.target.value, 'firstNameInput'))
dispatch(updateValue('Doe', 'lastNameInput'))
The code at the beginning of the answer is a generic version of the latter.

Resources