[英]Accessing a part of reducer state from one reducer within another reducer
我不知道如何從reducerRegister.js
中的reducerForm.js
reducer 訪問 boolean isLoading
標志。 我使用combineReducers()
並使用isLoading
在表單提交期間禁用按鈕。
它的初始狀態是 false,點擊提交后,它變為true
。 表單提交成功后,再次將isLoading
重置為false
。 下面是這個問題的相關代碼:
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
的地方:
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
};
}
這在 Redux 常見問題解答中有所介紹,網址為https://redux.js.org/faq/reducers#how-do-i-share-state-between-two-reducers-do-i-have-to-use-combinereducers :
許多用戶后來想嘗試在兩個 reducer 之間共享數據,但發現 combineReducers 不允許他們這樣做。 有幾種方法可以使用:
- 如果一個 reducer 需要了解來自另一個狀態片的數據,則可能需要重新組織狀態樹形狀,以便單個 reducer 可以處理更多數據。
- 您可能需要編寫一些自定義函數來處理其中一些操作。 這可能需要用您自己的頂級 reducer 函數替換 combineReducers。 您還可以使用諸如 reduce-reducers 之類的實用程序來運行 combineReducers 來處理大多數操作,但也可以為跨狀態切片的特定操作運行更專業的 reducer。
- redux-thunk 等異步操作創建者可以通過 getState() 訪問整個狀態。 action creator 可以從狀態中檢索額外的數據並將其放入 action 中,這樣每個 reducer 都有足夠的信息來更新自己的狀態片。
一個 reducer 不能訪問另一個 reducer 的狀態,但是如果你使用redux-thunk ,你可以在 action creator 中這樣做。 例如,您可以像這樣定義一個動作創建者:
export const someAction = () =>
(dispatch, getState) => {
const someVal = getState().someReducer.someVal;
dispatch({ type: types.SOME_ACTION, valFromOtherReducer: someVal });
};
React Redux 適用於單向數據流。
Action ---> Reducer /store ---> Reducer
Reducer 在小的 store 子集上工作,你不能訪問不屬於 Reducer 的 reducer 內部的 store。 您可能需要根據 reducer 狀態返回從組件中觸發新操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.