Je ne sais pas comment accéder à un indicateur booléen isLoading
depuis le réducteur reducerForm.js
Dans reducerRegister.js
. J'ai utilisé combineReducers()
et j'utilise isLoading
pour désactiver un bouton lors de la soumission du formulaire.
Son état initial est faux, après avoir cliqué sur soumettre, il devient true
. Une fois la soumission du formulaire réussie, isLoading
est réinitialisé sur false
. Voici le code correspondant à ce problème:
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;
C'est là que j'utilise 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>
Mappage de l'état aux accessoires dans le même composant
function mapStateToProps(state) {
return {
errorMessage: state.signup.error,
isLoading: state.signup.isLoading,
values: state.form.values
};
}
Ceci est couvert dans le Redux FAQ at http://redux.js.org/docs/faq/Reducers.html#reducers-share-state :
De nombreux utilisateurs souhaitent par la suite essayer de partager des données entre deux réducteurs, mais constatent que combineReducers ne leur permet pas de le faire. Plusieurs approches peuvent être utilisées:
- Si un réducteur a besoin de connaître les données d'une autre tranche d'état, la forme de l'arborescence d'état peut avoir besoin d'être réorganisée de sorte qu'un seul réducteur gère plus de données.
- Vous devrez peut-être écrire certaines fonctions personnalisées pour gérer certaines de ces actions. Cela peut nécessiter le remplacement de combineReducers par votre propre fonction de réduction de niveau supérieur. Vous pouvez également utiliser un utilitaire tel que des réducteurs de réduction pour exécuter combineReducers pour gérer la plupart des actions, mais également exécuter un réducteur plus spécialisé pour des actions spécifiques qui traversent des tranches d'état.
- Les créateurs d'actions asynchrones tels que redux-thunk ont accès à l'état entier via getState (). Un créateur d'action peut récupérer des données supplémentaires de l'état et les mettre dans une action, de sorte que chaque réducteur dispose de suffisamment d'informations pour mettre à jour sa propre tranche d'état.
Un réducteur ne peut pas accéder à l'état d'un autre réducteur, mais si vous utilisez redux-thunk vous pouvez le faire à partir d'un créateur d'action. Par exemple, vous pouvez définir un créateur d'action comme celui-ci:
export const someAction = () =>
(dispatch, getState) => {
const someVal = getState().someReducer.someVal;
dispatch({ type: types.SOME_ACTION, valFromOtherReducer: someVal });
};
React Redux fonctionne sur un flux de données unidirectionnel.
Action ---> Reducer /store ---> Reducer
Le réducteur fonctionne sur un petit sous-ensemble de magasin, vous ne pouvez pas accéder au magasin à l'intérieur du réducteur qui ne fait pas partie du réducteur. vous pouvez soit déclencher une nouvelle action à partir du composant en fonction du retour d'état du réducteur.