_reducerForm.js
_の_reducerRegister.js
_レデューサーからブール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 FAQ at http://redux.js.org/docs/faq/Reducers.html#reducers-share-state :
多くのユーザーは、後で2つのレデューサー間でデータを共有しようとしますが、combinedReducersではそれらを許可しないことに気付きます。使用できるアプローチはいくつかあります。
- レデューサーが別の状態のスライスからのデータを知る必要がある場合、単一のレデューサーがより多くのデータを処理するように、状態ツリーの形状を再編成する必要がある場合があります。
- これらのアクションの一部を処理するために、いくつかのカスタム関数を作成する必要がある場合があります。これには、combineReducersを独自の最上位レデューサー関数に置き換える必要がある場合があります。また、reduce-reducersなどのユーティリティを使用して、combineReducersを実行してほとんどのアクションを処理できますが、状態スライスを横断する特定のアクションに対して、より特化したリデューサーを実行することもできます。
- Redux-thunkなどの非同期アクション作成者は、getState()を介して状態全体にアクセスできます。アクション作成者は、状態から追加のデータを取得してアクションに入れることができます。これにより、各レデューサーは自身の状態スライスを更新するのに十分な情報を取得できます。
レデューサーは別のレデューサーの状態にアクセスできませんが、 redux-thunk を使用している場合は、アクション作成者からアクセスできます。例として、次のようなアクションクリエーターを定義できます。
export const someAction = () =>
(dispatch, getState) => {
const someVal = getState().someReducer.someVal;
dispatch({ type: types.SOME_ACTION, valFromOtherReducer: someVal });
};
React Reduxは単方向のデータフローで動作します。
Action ---> Reducer /store ---> Reducer
Reducerは、ストアの小さなサブセットで動作します。Reducerの一部ではないreducer内のストアにはアクセスできません。リデューサーの状態の戻り値に基づいて、コンポーネントから新しいアクションを起動する必要があります。