Reducers with same action affect multiple screens
I have two reducers which share some actions. Issue is when i dispatch action on one screen it triggers action on the other screen. Boths screen are in a TabNavigator therefore I can easily see that if I change a field on 1 screen the same field is changed on the other screen as well.
Reducer 1
import * as Actions from '../actions/Types';
const initialState = {
email: '',
password: ''
};
const signInReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
default:
return state;
}
}
export default signInReducer;
Reducer 2
import * as Actions from '../actions/Types';
const initialState = {
firstName: '',
lastName: '',
email: '',
password: '',
repeatPassword: ''
};
const signUpReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_FIRST_NAME_INPUT:
return Object.assign({}, state,
{ firstName: action.firstName }
);
case Actions.CHANGE_LAST_NAME_INPUT:
return Object.assign({}, state,
{ lastName: action.lastName }
);
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
case Actions.CHANGE_REPEAT_PASSWORD_INPUT:
return Object.assign({}, state,
{ repeatPassword: action.password }
);
default:
return state;
}
}
export default signUpReducer;
Store
import { createStore, combineReducers } from 'redux';
import signInReducer from '../reducers/SignIn';
import signUpReducer from '../reducers/SignUp';
import profileReducer from '../reducers/Profile';
const rootReducer = combineReducers({
signIn: signInReducer,
signUp: signUpReducer,
profile: profileReducer
});
const configureStore = () => {
return createStore(rootReducer);
}
export default configureStore;
As you can see there are some common actions like CHANGE_EMAIL_INPUT & CHANGE_PASSWORD_INPUT and I dont want them to be triggered together. One way I can figure out is to change the name of actions and make then more specific to screen but this doesn't sound good. Another could be to wrap reducers so that we know what is being called but not getting an idea on the wrapper.
Any suggestions.
react-native react-redux
add a comment |
I have two reducers which share some actions. Issue is when i dispatch action on one screen it triggers action on the other screen. Boths screen are in a TabNavigator therefore I can easily see that if I change a field on 1 screen the same field is changed on the other screen as well.
Reducer 1
import * as Actions from '../actions/Types';
const initialState = {
email: '',
password: ''
};
const signInReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
default:
return state;
}
}
export default signInReducer;
Reducer 2
import * as Actions from '../actions/Types';
const initialState = {
firstName: '',
lastName: '',
email: '',
password: '',
repeatPassword: ''
};
const signUpReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_FIRST_NAME_INPUT:
return Object.assign({}, state,
{ firstName: action.firstName }
);
case Actions.CHANGE_LAST_NAME_INPUT:
return Object.assign({}, state,
{ lastName: action.lastName }
);
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
case Actions.CHANGE_REPEAT_PASSWORD_INPUT:
return Object.assign({}, state,
{ repeatPassword: action.password }
);
default:
return state;
}
}
export default signUpReducer;
Store
import { createStore, combineReducers } from 'redux';
import signInReducer from '../reducers/SignIn';
import signUpReducer from '../reducers/SignUp';
import profileReducer from '../reducers/Profile';
const rootReducer = combineReducers({
signIn: signInReducer,
signUp: signUpReducer,
profile: profileReducer
});
const configureStore = () => {
return createStore(rootReducer);
}
export default configureStore;
As you can see there are some common actions like CHANGE_EMAIL_INPUT & CHANGE_PASSWORD_INPUT and I dont want them to be triggered together. One way I can figure out is to change the name of actions and make then more specific to screen but this doesn't sound good. Another could be to wrap reducers so that we know what is being called but not getting an idea on the wrapper.
Any suggestions.
react-native react-redux
1
You should name them differently.
– Yossi
Nov 15 '18 at 9:17
add a comment |
I have two reducers which share some actions. Issue is when i dispatch action on one screen it triggers action on the other screen. Boths screen are in a TabNavigator therefore I can easily see that if I change a field on 1 screen the same field is changed on the other screen as well.
Reducer 1
import * as Actions from '../actions/Types';
const initialState = {
email: '',
password: ''
};
const signInReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
default:
return state;
}
}
export default signInReducer;
Reducer 2
import * as Actions from '../actions/Types';
const initialState = {
firstName: '',
lastName: '',
email: '',
password: '',
repeatPassword: ''
};
const signUpReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_FIRST_NAME_INPUT:
return Object.assign({}, state,
{ firstName: action.firstName }
);
case Actions.CHANGE_LAST_NAME_INPUT:
return Object.assign({}, state,
{ lastName: action.lastName }
);
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
case Actions.CHANGE_REPEAT_PASSWORD_INPUT:
return Object.assign({}, state,
{ repeatPassword: action.password }
);
default:
return state;
}
}
export default signUpReducer;
Store
import { createStore, combineReducers } from 'redux';
import signInReducer from '../reducers/SignIn';
import signUpReducer from '../reducers/SignUp';
import profileReducer from '../reducers/Profile';
const rootReducer = combineReducers({
signIn: signInReducer,
signUp: signUpReducer,
profile: profileReducer
});
const configureStore = () => {
return createStore(rootReducer);
}
export default configureStore;
As you can see there are some common actions like CHANGE_EMAIL_INPUT & CHANGE_PASSWORD_INPUT and I dont want them to be triggered together. One way I can figure out is to change the name of actions and make then more specific to screen but this doesn't sound good. Another could be to wrap reducers so that we know what is being called but not getting an idea on the wrapper.
Any suggestions.
react-native react-redux
I have two reducers which share some actions. Issue is when i dispatch action on one screen it triggers action on the other screen. Boths screen are in a TabNavigator therefore I can easily see that if I change a field on 1 screen the same field is changed on the other screen as well.
Reducer 1
import * as Actions from '../actions/Types';
const initialState = {
email: '',
password: ''
};
const signInReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
default:
return state;
}
}
export default signInReducer;
Reducer 2
import * as Actions from '../actions/Types';
const initialState = {
firstName: '',
lastName: '',
email: '',
password: '',
repeatPassword: ''
};
const signUpReducer = (state = initialState, action) => {
switch(action.type) {
case Actions.CHANGE_FIRST_NAME_INPUT:
return Object.assign({}, state,
{ firstName: action.firstName }
);
case Actions.CHANGE_LAST_NAME_INPUT:
return Object.assign({}, state,
{ lastName: action.lastName }
);
case Actions.CHANGE_EMAIL_INPUT:
return Object.assign({}, state,
{ email: action.email }
);
case Actions.CHANGE_PASSWORD_INPUT:
return Object.assign({}, state,
{ password: action.password }
);
case Actions.CHANGE_REPEAT_PASSWORD_INPUT:
return Object.assign({}, state,
{ repeatPassword: action.password }
);
default:
return state;
}
}
export default signUpReducer;
Store
import { createStore, combineReducers } from 'redux';
import signInReducer from '../reducers/SignIn';
import signUpReducer from '../reducers/SignUp';
import profileReducer from '../reducers/Profile';
const rootReducer = combineReducers({
signIn: signInReducer,
signUp: signUpReducer,
profile: profileReducer
});
const configureStore = () => {
return createStore(rootReducer);
}
export default configureStore;
As you can see there are some common actions like CHANGE_EMAIL_INPUT & CHANGE_PASSWORD_INPUT and I dont want them to be triggered together. One way I can figure out is to change the name of actions and make then more specific to screen but this doesn't sound good. Another could be to wrap reducers so that we know what is being called but not getting an idea on the wrapper.
Any suggestions.
react-native react-redux
react-native react-redux
edited Nov 15 '18 at 12:27
Yossi
1,8502721
1,8502721
asked Nov 15 '18 at 8:52
Nikhil GuptaNikhil Gupta
3532326
3532326
1
You should name them differently.
– Yossi
Nov 15 '18 at 9:17
add a comment |
1
You should name them differently.
– Yossi
Nov 15 '18 at 9:17
1
1
You should name them differently.
– Yossi
Nov 15 '18 at 9:17
You should name them differently.
– Yossi
Nov 15 '18 at 9:17
add a comment |
2 Answers
2
active
oldest
votes
You should not reuse the same action name between 2 reducers, to avoid unintended effects, use different names.
For example
Actions.SIGNUP_ CHANGE_EMAIL_INPUT
and
Actions.SIGNIN_ CHANGE_EMAIL_INPUT
Otherwise, you can merge your 2 reducers, adding a state to know from which screen this change emerged.
add a comment |
well, i solved it by creating a wrapper for the reducers.
Store
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const isInitializationCall = state === undefined;
const shouldRunWrappedReducer = reducerName(action) || isInitializationCall;
return shouldRunWrappedReducer ? reducerFunction(state, action) : state;
}
}
const rootReducer = combineReducers({
// signIn: signInReducer,
// signUp: signUpReducer,
// profile: profileReducer
signIn: createNamedWrapperReducer(signInReducer, action => action.name === 'signIn'),
signUp: createNamedWrapperReducer(signUpReducer, action => action.name === 'signUp'),
profile: createNamedWrapperReducer(profileReducer, action => action.name === 'profile'),
});
Screen
onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53315579%2freducers-with-same-action-affect-multiple-screens%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should not reuse the same action name between 2 reducers, to avoid unintended effects, use different names.
For example
Actions.SIGNUP_ CHANGE_EMAIL_INPUT
and
Actions.SIGNIN_ CHANGE_EMAIL_INPUT
Otherwise, you can merge your 2 reducers, adding a state to know from which screen this change emerged.
add a comment |
You should not reuse the same action name between 2 reducers, to avoid unintended effects, use different names.
For example
Actions.SIGNUP_ CHANGE_EMAIL_INPUT
and
Actions.SIGNIN_ CHANGE_EMAIL_INPUT
Otherwise, you can merge your 2 reducers, adding a state to know from which screen this change emerged.
add a comment |
You should not reuse the same action name between 2 reducers, to avoid unintended effects, use different names.
For example
Actions.SIGNUP_ CHANGE_EMAIL_INPUT
and
Actions.SIGNIN_ CHANGE_EMAIL_INPUT
Otherwise, you can merge your 2 reducers, adding a state to know from which screen this change emerged.
You should not reuse the same action name between 2 reducers, to avoid unintended effects, use different names.
For example
Actions.SIGNUP_ CHANGE_EMAIL_INPUT
and
Actions.SIGNIN_ CHANGE_EMAIL_INPUT
Otherwise, you can merge your 2 reducers, adding a state to know from which screen this change emerged.
answered Nov 15 '18 at 13:31
VinzzzVinzzz
10.5k42938
10.5k42938
add a comment |
add a comment |
well, i solved it by creating a wrapper for the reducers.
Store
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const isInitializationCall = state === undefined;
const shouldRunWrappedReducer = reducerName(action) || isInitializationCall;
return shouldRunWrappedReducer ? reducerFunction(state, action) : state;
}
}
const rootReducer = combineReducers({
// signIn: signInReducer,
// signUp: signUpReducer,
// profile: profileReducer
signIn: createNamedWrapperReducer(signInReducer, action => action.name === 'signIn'),
signUp: createNamedWrapperReducer(signUpReducer, action => action.name === 'signUp'),
profile: createNamedWrapperReducer(profileReducer, action => action.name === 'profile'),
});
Screen
onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },
add a comment |
well, i solved it by creating a wrapper for the reducers.
Store
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const isInitializationCall = state === undefined;
const shouldRunWrappedReducer = reducerName(action) || isInitializationCall;
return shouldRunWrappedReducer ? reducerFunction(state, action) : state;
}
}
const rootReducer = combineReducers({
// signIn: signInReducer,
// signUp: signUpReducer,
// profile: profileReducer
signIn: createNamedWrapperReducer(signInReducer, action => action.name === 'signIn'),
signUp: createNamedWrapperReducer(signUpReducer, action => action.name === 'signUp'),
profile: createNamedWrapperReducer(profileReducer, action => action.name === 'profile'),
});
Screen
onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },
add a comment |
well, i solved it by creating a wrapper for the reducers.
Store
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const isInitializationCall = state === undefined;
const shouldRunWrappedReducer = reducerName(action) || isInitializationCall;
return shouldRunWrappedReducer ? reducerFunction(state, action) : state;
}
}
const rootReducer = combineReducers({
// signIn: signInReducer,
// signUp: signUpReducer,
// profile: profileReducer
signIn: createNamedWrapperReducer(signInReducer, action => action.name === 'signIn'),
signUp: createNamedWrapperReducer(signUpReducer, action => action.name === 'signUp'),
profile: createNamedWrapperReducer(profileReducer, action => action.name === 'profile'),
});
Screen
onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },
well, i solved it by creating a wrapper for the reducers.
Store
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const isInitializationCall = state === undefined;
const shouldRunWrappedReducer = reducerName(action) || isInitializationCall;
return shouldRunWrappedReducer ? reducerFunction(state, action) : state;
}
}
const rootReducer = combineReducers({
// signIn: signInReducer,
// signUp: signUpReducer,
// profile: profileReducer
signIn: createNamedWrapperReducer(signInReducer, action => action.name === 'signIn'),
signUp: createNamedWrapperReducer(signUpReducer, action => action.name === 'signUp'),
profile: createNamedWrapperReducer(profileReducer, action => action.name === 'profile'),
});
Screen
onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },
answered Nov 15 '18 at 9:22
Nikhil GuptaNikhil Gupta
3532326
3532326
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53315579%2freducers-with-same-action-affect-multiple-screens%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You should name them differently.
– Yossi
Nov 15 '18 at 9:17