J'ai vu des réponses contradictoires (ou tout simplement déroutantes pour moi) dans d'autres questions ici concernant si l'utilisation de getState
dans une action est acceptable ou non, et j'ai vu à plusieurs reprises que cela était appelé un anti-modèle . Pour moi, cela semble fonctionner très bien, mais quelle est la meilleure pratique pour le faire si nous ne devons pas utiliser getState
?
J'utilise getState
dans un thunk pour filtrer à travers un tableau d'utilisateurs qui est actuellement connecté à certaines données fictives et qui est tiré dans l'état de l'application.
Voici le code de mon action:
export const accountLogInSuccess = user => ({
type: types.ACCOUNT_LOG_IN_SUCCESS,
user,
});
export const accountLogOutSuccess = () => ({
type: types.ACCOUNT_LOG_OUT_SUCCESS,
});
export const accountCheckSuccess = () => ({
type: types.ACCOUNT_CHECK_SUCCESS,
});
export const accountCheck = () => (
(dispatch, getState) => {
dispatch(ajaxCallBegin());
return apiAccount.accountCheck().then((account) => {
if (account) {
const user = findByUID(getState().users, account.uid);
dispatch(accountLogInSuccess(user));
toastr.success(`Welcome ${user.nameFirst}!`);
} else {
dispatch(accountLogOutSuccess());
}
dispatch(accountCheckSuccess());
}).catch((error) => {
dispatch(ajaxCallError(error));
toastr.error(error.message);
throw (error);
});
}
);
Et mon réducteur:
export default function reducerAccount(state = initial.account, action) {
switch (action.type) {
case types.ACCOUNT_LOG_IN_SUCCESS:
return Object.assign({}, state, action.user, {
authenticated: true,
});
case types.ACCOUNT_LOG_OUT_SUCCESS:
return Object.assign({}, {
authenticated: false,
});
case types.ACCOUNT_CHECK_SUCCESS:
return Object.assign({}, state, {
initialized: true,
});
default:
return state;
}
}
L'état de compte initial utilisé dans mon réducteur est juste:
account: {
initialized: false,
authenticated: false,
},
L'action accountCheck
transmet l'utilisateur (trouvé à l'aide de getState
et de la fonction findByUID
) dans accountLogInSuccess
où le réducteur ajoute ses valeurs à l'état actuel du compte via Object.assign
.
Préférant ne pas avoir à placer l'utilisateur à la racine de mon application, puis à le transmettre via des accessoires, quelle est la meilleure pratique pour y parvenir au sein de Redux et que les données utilisateur soient disponibles à l'état? Encore une fois, l'utilisation de getState
dans le thunk me convient jusqu'à présent, mais y a-t-il une meilleure solution à cela qui n'est pas considérée comme un anti-modèle?
J'ai écrit un article de blog étendu intitulé Idiomatic Redux: Réflexions sur les thunks, les sagas, l'abstraction et la réutilisation , qui aborde ce sujet en détail. Dans ce document, je réponds à plusieurs critiques des thunks et de l'utilisation de getState
(y compris les commentaires de Dan Abramov dans Accéder à l'état Redux dans un créateur d'action? ). En fait, mon message a été spécifiquement inspiré par des questions comme la vôtre.
En tant que TL; DR de mon message: je crois que les thunks sont un outil complètement viable pour une utilisation dans les applications Redux et j'encourage leur utilisation. Bien qu'il existe certaines préoccupations valables à prendre en compte lors de l'utilisation de thunks et de sagas, et en utilisant getState/select
à l'intérieur d'eux, ces préoccupations ne devraient pas vous effrayer d'utiliser des thunks.