从另一个减速器中的一个减速器访问减速器状态的一部分 [英] Accessing a part of reducer state from one reducer within another reducer

查看:17
本文介绍了从另一个减速器中的一个减速器访问减速器状态的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何从 reducerRegister.js 中的 reducerForm.js 减速器访问布尔 isLoading 标志.我使用了 combineReducers() 并使用 isLoading 在表单提交期间禁用按钮.

I do not know how to access a boolean isLoading flag from reducerForm.js reducer in reducerRegister.js. I have used combineReducers() and I use isLoading to disable a button during form submit.

初始状态为false,点击提交后,变为true.表单提交成功后,isLoading再次重置为false.以下是此问题的相关代码:

It's initial state is false, after clicking submit, it changes to true. After the form submission is successful, isLoading is reset to false again. Below is the relevant code for this issue:

actionRegister.js

let _registerUserFailure = (payload) => {
    return {
        type: types.SAVE_USER_FAILURE,
        payload
    };
};
let _registerUserSuccess = (payload) => {
    return {
        type: types.SAVE_USER_SUCCESS,
        payload,
        is_Active: 0,
        isLoading:true
    };
};

let _hideNotification = (payload) => {
    return {
        type: types.HIDE_NOTIFICATION,
        payload: ''
    };
};

// asynchronous helpers
export function registerUser({ // use redux-thunk for asynchronous dispatch
    timezone,
    password,
    passwordConfirmation,
    email,
    name
}) {
    return dispatch => {
        axios.all([axios.post('/auth/signup', {
                    timezone,
                    password,
                    passwordConfirmation,
                    email,
                    name,
                    is_Active: 0
                })
                // axios.post('/send', {email})
            ])
            .then(axios.spread(res => {
                dispatch(_registerUserSuccess(res.data.message));
                dispatch(formReset());
                setTimeout(() => {
                    dispatch(_hideNotification(res.data.message));
                }, 10000);
            }))
            .catch(res => {
                // BE validation and passport error message
                dispatch(_registerUserFailure(res.data.message));
                setTimeout(() => {
                    dispatch(_hideNotification(res.data.message));
                }, 10000);
            });
    };
} 

actionForm.js

export function formUpdate(name, value)  {
    return {
        type: types.FORM_UPDATE_VALUE,
        name, //shorthand from name:name introduced in ES2016
        value
    };
}
export function formReset() {
  return {
    type: types.FORM_RESET
  };
}

reducerRegister.js

const INITIAL_STATE = {
  error:{},
  is_Active:false,
  isLoading:false
};
const reducerSignup = (state = INITIAL_STATE , action) => {
  switch(action.type) {
    case types.SAVE_USER_SUCCESS:
      return { ...state, is_Active:false, isLoading: true, error: { register: action.payload }};
      case types.SAVE_USER_FAILURE:
      return { ...state, error: { register: action.payload }};
      case types.HIDE_NOTIFICATION:
      return { ...state , error:{} };
   }
      return state;
};
export default reducerSignup;

reducerForm.js

const INITIAL_STATE = {
    values: {}
};
const reducerUpdate = (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case types.FORM_UPDATE_VALUE:
            return Object.assign({}, state, {
                values: Object.assign({}, state.values, {
                    [action.name]: action.value,
                })
            });
        case types.FORM_RESET:
        return INITIAL_STATE;
        // here I need isLoading value from reducerRegister.js
    }
    return state;
};
export default reducerUpdate;

reducerCombined.js

import { combineReducers } from 'redux';
import reducerRegister from './reducerRegister';
import reducerLogin from './reducerLogin';
import reducerForm from './reducerForm';

const rootReducer = combineReducers({
  signup:reducerRegister,
  signin: reducerLogin,
  form: reducerForm
});

export default rootReducer;

这是我使用 isLoading 的地方:

This is where I use isLoading:

  let isLoading = this.props.isLoading;
<FormGroup>
    <Col smOffset={4} sm={8}>
     <Button type="submit"  disabled={isLoading}
       onClick={!isLoading ? isLoading : null}
     >
     { isLoading ? 'Creating...' : 'Create New Account'}
       </Button>
   </Col>
       </FormGroup>

将 state 映射到同一个组件内的 props

Mapping state to props within the same component

function mapStateToProps(state) {
    return {
        errorMessage: state.signup.error,
    isLoading: state.signup.isLoading,
    values: state.form.values

    };
}

推荐答案

https://redux.js.org/faq/reducers#how-do-i-share-两个减速器之间的状态-我必须使用-组合减速器:

很多用户后来想尝试在两个reducer之间共享数据,但是发现 combineReducers 不允许他们这样做.有几种方法可以使用:

Many users later want to try to share data between two reducers, but find that combineReducers does not allow them to do so. There are several approaches that can be used:

  • 如果一个 reducer 需要知道来自另一个状态切片的数据,则可能需要重新组织状态树的形状,以便单个 reducer 处理更多的数据.
  • 您可能需要编写一些自定义函数来处理其中一些操作.这可能需要用您自己的顶级 reducer 函数替换 combineReducers.您还可以使用诸如 reduce-reducers 之类的实用程序来运行 combineReducers 来处理大多数操作,但也可以为跨状态切片的特定操作运行更专业的 reducer.
  • 诸如 redux-thunk 之类的异步操作创建者可以通过 getState() 访问整个状态.动作创建者可以从状态中检索额外的数据并将其放入动作中,以便每个减速器都有足够的信息来更新自己的状态片.

这篇关于从另一个减速器中的一个减速器访问减速器状态的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆