2017-02-15 133 views
2

我有一個小問題,即我不知道如何從reducerRegister.js中的reducerForm.js reducer訪問isLoading值,我嘗試了所有我能想到的,所以我現在被卡住了。只是想提一下,我已經使用了combineReducers函數,並且我在提交後使用isLoading值來禁用按鈕,所以它的初始狀態是false,點擊提交後它會得到真值,並且在表單成功發佈後它會得到錯誤的值再次。下面是這個問題的所有相關代碼:從另一個reducer中的一個reducer訪問reducer狀態的一部分

/* * 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 => { 
       dispatch(_registerUserFailure(res.data.message)); //BE validation and passport error 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; 

/*這是從組件,其中i使用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> 

/*和映射狀態道具從同一部件*/

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

    }; 
} 

回答

3

這是包括在終極版常見問題解答:舉個例子,你可以定義一個動作的創造者這樣

許多用戶以後想嘗試兩個減速器之間共享數據,但發現combineReducers不允許他們這樣做。有跡象表明,可以用幾種方法:

  • 如果減速需要知道從國家的另一片數據時,狀態樹形狀可能需要重新安排,一個減速器處理更多的數據。
  • 您可能需要編寫一些自定義函數來處理其中的一些操作。這可能需要用您自己的頂級減速器功能替換combineReducers。您還可以使用諸如reduce-reducers之類的實用程序來運行combineReducers以處理大多數操作,但也可以針對跨狀態切片的特定操作運行更專用的Reducer。
  • 異步動作創建者(如redux-thunk)可以通過getState()訪問整個狀態。動作創建者可以從狀態中檢索附加數據並將其放入動作中,以便每個縮減器都有足夠的信息來更新其自己的狀態片。
+0

謝謝,@markerikson,錯過文檔的一部分,會讀,但最後的方法似乎是最好的我的getState() –

0

React Redux適用於單向數據流。

Action ---> Reducer /store ---> Reducer 

減速機適用於小型商店的子集,您不能訪問Reducer中不屬於Reducer的商店。您可以根據Reducer狀態返回來從組件中觸發新的操作。

相關問題