具有相同动作的减速器会影响多个屏幕

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有相同动作的减速器会影响多个屏幕相关的知识,希望对你有一定的参考价值。

我有两个减速器分享一些动作。问题是当我在一个屏幕上发送操作时,它会在另一个屏幕上触发操作。两个屏幕都在TabNavigator中,因此我可以很容易地看到,如果我在1个屏幕上更改字段,则同一个字段也会在另一个屏幕上更改。

减速机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;

减速机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;

商店

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;

正如您所看到的,有一些常见的操作,如CHANGE_EMAIL_INPUT和CHANGE_PASSWORD_INPUT,我不希望它们一起被触发。我可以弄清楚的一种方法是更改​​操作的名称,然后使屏幕更具体,但这听起来不太好。另一个可能是包装Reducer,以便我们知道被调用的内容但是没有在包装器上得到一个想法。

有什么建议。

答案

您不应在2个reducer之间重复使用相同的操作名称,以避免意外的影响,使用不同的名称。

例如

Actions.SIGNUP_ CHANGE_EMAIL_INPUTActions.SIGNIN_ CHANGE_EMAIL_INPUT

否则,您可以合并您的2个Reducer,添加一个状态以了解此更改出现在哪个屏幕上。

另一答案

好吧,我通过为减速器创建一个包装器来解决它。

商店

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'),
});

屏幕

onChangeEmail: (email) => { dispatch({name: 'signIn', type: Actions.CHANGE_EMAIL_INPUT, email: email}) },

以上是关于具有相同动作的减速器会影响多个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

使用通用动作和减速器简化 redux

图像上的OnClick()会添加具有不同信息的相同片段

具有相同布局的多个片段

使用具有不同片段字段的相同中继根查询的多个 react-router-relay 路由

作用于多个商店的动作

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段