I have read many articles and examples, but I dont find a method to simplify a nested state. Is this possible to udpate a state without using a rest operator by property like the partial code below ?
const initialState = {
currentTag: 'fr-FR',
locales: {
components: [],
},
};
const setComponentsLocales = (state, payload) => ({
...state,
[payload.oid]: payload.locales,
});
const localesReducer = (state, action) => {
switch (action.type) {
case types.SET_COMPONENT_LOCALES:
return {
...state,
components: setComponentsLocales(state.components, action.payload),
};
default:
return state;
}
};
export default (state = initialState, action) => {
switch (action.type) {
case types.SET_LANGUAGE:
return {
...state,
currentTag: action.payload.tag,
};
default:
return {
...state,
locales: localesReducer(state.locales, action),
};
}
};
Related
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;
};
}
How to merge the existing state with the new state in react native using redux?"
i tried these
const Initial_State = { images: [] };
export default (state = Initial_State, action) => {
switch (action.type) {
case 'ImagesFetch':
return {...state, images: action.payload};
default:
return state;
}
}
these two are returning the new state but not showing the previous state
const Initial_State = { images: [] };
export default (state = Initial_State, action) => {
switch (action.type) {
case 'ImagesFetch':
return {...state, images: [...action.payload]};
default:
return state;
}
}
const Initial_State = { images: [] };
export default (state = Initial_State, action) => {
switch (action.type) {
case 'ImagesFetch':
return [...state, ...action.payload.images];
default:
return state;
}
}
and the one is throwing and error, none of the above worked
try this:
const Initial_State = { images: [] };
export default (state = Initial_State, action) => {
switch (action.type) {
case 'ImagesFetch':
return {
images: [...state.images, action.payload]
};
default:
return state;
}
}
Or better to safe if in the future you add to state other properties:
const Initial_State = { images: [] };
export default (state = Initial_State, action) => {
switch (action.type) {
case 'ImagesFetch':
return {
...state,
images: [...state.images, action.payload]
};
default:
return state;
}
}
I'm trying to find what would be the best pattern to manage my reducers.
I have the following page:
I know I could've used redux-forms for this, but this is not the point since I only used these fields/form as an example.
We have multiple ways of handling this on redux:
1: having a single action to update those fields values based on the input's name property:
const UPDATE_VALUES = 'UPDATE_VALUES';
const INITIAL_STATE = {
aString: '',
setOfValues1: [],
setOfValues2: []
};
const reducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case UPDATE_VALUES: {
if (action.name === 'setOfValues1' || action.name === 'setOfValues2') {
const array = [...state[action.name]];
array.push(action.value);
return {
...state,
[action.name]: array
};
}
return {
...state,
[action.name]: action.value
};
}
default:
return state;
}
};
2: having multiple actions to each field value:
const UPDATE_A_STRING = 'UPDATE_A_STRING';
const UPDATE_SET_1 = 'UPDATE_SET_1';
const UPDATE_SET_2 = 'UPDATE_SET_2';
const INITIAL_STATE = {
aString: '',
setOfValues1: [],
setOfValues2: []
};
const reducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case UPDATE_A_STRING:
return {
...state,
aString: action.value
};
case UPDATE_SET_1: {
const array = [...state.setOfValues1];
array.push(action.value);
return {
...state,
setOfValues1: array
};
}
case UPDATE_SET_2: {
const array = [...state.setOfValues2];
array.push(action.value);
return {
...state,
setOfValues2: array
};
}
default:
return state;
}
};
and more ways that I'm not aware of.
what would be the good practice/best pattern in this case? Where can I look for, to learn more patterns to situations like these and other situations as well?
What about this?
const UPDATE_VALUES = 'UPDATE_VALUES';
const INITIAL_STATE = {
aString: '',
setOfValues1: [],
setOfValues2: []
};
const setOfValues = ['setOfValues1', 'setOfValues2'];
const reducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case UPDATE_VALUES: {
if (setOfValues.includes(action.name)) {
return {
...state,
[action.name]: state[action.name].concat(action.value);
};
}
return {
...state,
[action.name]: action.value
};
}
default:
return state;
}
};
I want to update the state of activitiesData when ACTIVITIES_SEND_SUCCESS is executed by appending the new data to the end of the object activitiesData.
ActivitiesReducer.js
import {
ACTIVITIES_FETCH_SUCCESS,
ACTIVITIES_SEND_SUCCESS,
SUBACTIVITY_SEND_SUCCESS
} from '../actions/types';
const INITIAL_STATE = { activitiesData: {}, activityCreated: {}, listActivity: {} };
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case ACTIVITIES_FETCH_SUCCESS:
return { ...state, activitiesData: action.payload };
case ACTIVITIES_SEND_SUCCESS:
return { ...state, activityCreated: action.payload };
case SUBACTIVITY_SEND_SUCCESS:
return { ...state, listActivity: action.payload };
default:
return state;
}
};
You can append the data using spread operator syntax like
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case ACTIVITIES_FETCH_SUCCESS:
return { ...state, activitiesData: action.payload };
case ACTIVITIES_SEND_SUCCESS:
return { ...state, activityCreated: action.payload, activitiesData: {...state.activitesData, ...action.payload } };
case SUBACTIVITY_SEND_SUCCESS:
return { ...state, listActivity: action.payload};
default:
return state;
}
};
I'm working on react-native app with redux. I can't delete specific item from array. state.tournaments is array and item which i want to delete must contain ID which I'm sending from actions to redux.
This is my reducer:
import {
TOURNAMENT_NAME_CHANGED,
TOURNAMENT_CREATE,
SAVE_TOURNAMENT,
DELETE_TOURNAMENT
} from '../actions/types';
const INITIAL_STATE = {
name: null,
admin_token: null,
tournaments: []
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case TOURNAMENT_NAME_CHANGED:
return { ...state, name: action.payload };
case TOURNAMENT_CREATE:
return { ...state, admin_token: action.payload.data.admin_token };
case SAVE_TOURNAMENT:
return { ...state, tournaments: [...state.tournaments, action.payload] };
case DELETE_TOURNAMENT:
return { ...state, tournaments: state.tournaments.filter((name, id) => id !== action.payload.id) };
default:
return state;
}
};
You're not using filter correctly, try this:
state.tournaments.filter(tournament => tournament.id !== action.payload.id)