【问题标题】:Calling an action triggers multiple reducers?调用一个动作会触发多个reducer?
【发布时间】:2020-02-25 17:21:21
【问题描述】:

我只在LoginAction 中发送了一个动作,但它触发了三个reducer。不知道为什么……

版本:

"react": "16.9.0",
"react-native": "0.61.2",
"react-redux": "^7.1.1",
"redux": "^4.0.4",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0",

这是我的设置。

App.js:

import React from 'react';
import ReduxThunk from 'redux-thunk';
import { Provider } from 'react-redux';
import { compose, createStore, applyMiddleware } from 'redux';
// import { persistStore } from 'redux-persist';
// import { PersistGate } from 'redux-persist/integration/react';
import reducers from './src/reducers';
import AppContainer from './src/navigator' // It is my react-navigation route

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const App: () => React$Node = () => {
  if (!__DEV__) {
    console.log = () => {};
  }

  const store = createStore(reducers, {}, composeEnhancers(applyMiddleware(ReduxThunk)));

  return (
    <Provider store={store}>
      <AppContainer />   
    </Provider>     
  );
};

export default App;

我的 LoginAction.js:

export const testAction = () => {
  return (dispatch) => {
    dispatch( { type: 'TEST_ACTION' });
  }
}

我的减速器设置: reducers/index.js

import { combineReducers } from 'redux';
import LoginReducer from './LoginReducer';
import StoreReducer from './StoreReducer';
import ReservationReducer from './ReservationReducer';

export default combineReducers({
  LoginRedux: LoginReducer,
  StoreRedux: StoreReducer,
  ReservationRedux: ReservationReducer
});

我的 LoginReducer.js:(StoreReducer 和 ReservationReducer 和 LoginReducer 一样)

const INITIAL_STATE = {
  ...my state arguments
};

export default (state = INITIAL_STATE, action) => {

  // Here is my issue !
  // StoreReducer is 'StoreReducer reducer =>', action
  // ReservationReducer is 'ReservationReducer reducer =>', action
  console.log('Login reducer =>', action);  

  switch (action.type) {
    case 'SOME_ACTION': 
      return {
        // state setting from action
      };
    default:
      return state;
    }
};

调用action组件是LoginScreen.js:

import React, { Component } from 'react';
import { 
  // some view
} from 'react-native';
import { connect } from 'react-redux';
import { login, closeLoadingCheckModal, testAction } from '../actions';

class LoginScreen extends Component {
  constructor(props) {
    super(props);

    this.state = { 
      // some states
    };
  }

  render() {
    return (
      <View>
        <TouchableOpacity onPress={() => { this.props.testAction() }>
          <Text>Press Test Action</Text>
        </TouchableOpacity>
      </View>
    );
  }
const mapStateToProps = (state) => {
  const { ...some store value  } = state.LoginRedux;

  return { ...some store value  };
};

}

export default connect(mapStateToProps, { login, closeLoadingCheckModal, testAction })(LoginScreen);

当我触发动作时,所有的 reducer 都会被触发。

它应该只是控制台日志Login reducer =&gt;

有人知道我的问题是什么吗?

【问题讨论】:

  • 这是预期的行为。所有减速器“看到”每一个动作。他们根据 action.type 决定是否响应。如果您不希望响应特定类型,请不要在该 reducer 中实现该类型。

标签: javascript react-native redux react-redux redux-thunk


【解决方案1】:

如果您使用combineReducers所有您的切片缩减器将为每个调度的操作运行。这是一个给定的 reducer 是否真的计算新状态的问题。

更多详情请见the Redux FAQ entry on "is there a 1:1 mapping between reducers and actions?"

【讨论】:

    【解决方案2】:

    如果多个reducer 实现相同的动作类型,一个动作确实可以结束更新多个reducer。在您的情况下,所有三个减速器都侦听TEST_ACTION 类型的操作。如果您不希望这种行为,您应该确保动作类型在整个应用程序中是唯一的,例如通过基于 reducer 的动作前缀。

    export const testAction = () => {
      return (dispatch) => {
        dispatch( { type: 'LOGIN_TEST_ACTION' });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 2017-10-03
      • 2021-10-06
      • 2014-09-21
      • 2019-10-20
      • 2020-01-15
      • 2022-11-22
      相关资源
      最近更新 更多