I've been learning React and Flux over the past few months, and one thing I've not yet dealt with is displaying error messages to users. Specifically, error messages that occur as a result of an ajax http request within a flux action creator method.
A simple example is user sign in - if the sign in ajax request fails due to a bad password, the server responds with the failure. At that moment, within my flux action creator method, my only option is to dispatch an action containing the error information, right?
I can dispatch the error information and keep that error in a store. I'm not sure what the best way to tie certain errors to certain components is, though. Lets say my react component tree is rendering multiple error-aware components, but an error occurs during server-side user auth attempt and needs to be displayed on that sign in form.
Is there good pattern or convention for storing errors and knowing which component they're for? Is there a programmatic way of determining this, instead of passing in some identifier to every action creator function that identifies the component the action creator is called it, etc?
Since you marked the question with Redux tag, I'm assuming you use Redux.
If so, this real-world example shows error handling.
There's a reducer that reacts to any action with error
field:
// Updates error message to notify about the failed fetches.
function errorMessage(state = null, action) {
const { type, error } = action;
if (type === ActionTypes.RESET_ERROR_MESSAGE) {
return null;
} else if (error) {
return action.error;
}
return state;
}
The custom API middleware puts any error message into error
field on the action:
return callApi(endpoint, schema).then(
response => next(actionWith({
response,
type: successType
})),
error => next(actionWith({
type: failureType,
error: error.message || 'Something bad happened'
}))
);
Finally, the component reads the error message from Redux store:
function mapStateToProps(state) {
return {
errorMessage: state.errorMessage
};
}
As you can see, this is not any different from how you'd handle displaying fetched data.
Your idea of keeping error info in a store is fine (probably an ErrorStore
). But the store doesn't need to know the component interested in a particular error. Instead, the ErrorStore
needs to emit a CHANGE
event. When emitting that event, you can add an additional argument, namely the error type (which the store presumably gets from the action creator).
Now, any component can listen to the ErrorStore
and check the error type (which it will get as an argument). Components can then know what kind of error was generated and decide whether they are interested in that or not.