score:128
If you want to have the concept of "global errors", you can create an errors
reducer, which can listen for addError, removeError, etc... actions. Then, you can hook into your Redux state tree at state.errors
and display them wherever appropriate.
There are a number of ways you could approach this, but the general idea is that global errors/messages would merit their own reducer to live completely separate from <Clients />
/<AppToolbar />
. Of course if either of these components needs access to errors
you could pass errors
down to them as a prop wherever needed.
Update: Code Example
Here is one example of what it might look like if you were to pass the "global errors" errors
into your top level <App />
and conditionally render it (if there are errors present). Using react-redux's connect
to hook up your <App />
component to some data.
// App.js
// Display "global errors" when they are present
function App({errors}) {
return (
<div>
{errors &&
<UserErrors errors={errors} />
}
<AppToolbar />
<Clients />
</div>
)
}
// Hook up App to be a container (react-redux)
export default connect(
state => ({
errors: state.errors,
})
)(App);
And as far as the action creator is concerned, it would dispatch (redux-thunk) success failure according to the response
export function fetchSomeResources() {
return dispatch => {
// Async action is starting...
dispatch({type: FETCH_RESOURCES});
someHttpClient.get('/resources')
// Async action succeeded...
.then(res => {
dispatch({type: FETCH_RESOURCES_SUCCESS, data: res.body});
})
// Async action failed...
.catch(err => {
// Dispatch specific "some resources failed" if needed...
dispatch({type: FETCH_RESOURCES_FAIL});
// Dispatch the generic "global errors" action
// This is what makes its way into state.errors
dispatch({type: ADD_ERROR, error: err});
});
};
}
While your reducer could simply manage an array of errors, adding/removing entries appropriately.
function errors(state = [], action) {
switch (action.type) {
case ADD_ERROR:
return state.concat([action.error]);
case REMOVE_ERROR:
return state.filter((error, i) => i !== action.index);
default:
return state;
}
}
score:-8
You can use axios HTTP client. It already has implemented Interceptors feature. You can intercept requests or responses before they are handled by then or catch.
https://github.com/mzabriskie/axios#interceptors
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
score:1
write custom Middleware to handle all the api related error. In this case your code will be more cleaner.
failure/ error actin type ACTION_ERROR
export default (state) => (next) => (action) => {
if(ACTION_ERROR.contains('_ERROR')){
// fire error action
store.dispatch(serviceError());
}
}
score:1
what I do is I centralize all error handling in the effect on a per effect basis
/**
* central error handling
*/
@Effect({dispatch: false})
httpErrors$: Observable<any> = this.actions$
.ofType(
EHitCountsActions.HitCountsError
).map(payload => payload)
.switchMap(error => {
return of(confirm(`There was an error accessing the server: ${error}`));
});
score:2
The approach I'm currently taking for a few specific errors (user input validation) is to have my sub-reducers throw an exception, catch it in my root reducer, and attach it to the action object. Then I have a redux-saga that inspects action objects for an error and update the state tree with error data in that case.
So:
function rootReducer(state, action) {
try {
// sub-reducer(s)
state = someOtherReducer(state,action);
} catch (e) {
action.error = e;
}
return state;
}
// and then in the saga, registered to take every action:
function *errorHandler(action) {
if (action.error) {
yield put(errorActionCreator(error));
}
}
And then adding the error to the state tree is as Erik describes.
I use it pretty sparingly, but it keeps me from having to duplicate logic which legitimately belongs in the reducer (so it can protect itself from an invalid state).
score:116
Erik’s answer is correct but I would like to add that you don’t have to fire separate actions for adding errors. An alternative approach is to have a reducer that handles any action with an error
field. This is a matter of personal choice and convention.
For example, from Redux real-world
example that has error handling:
// 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 error
}
return state
}
Source: stackoverflow.com
Related Query
- What is the best way to deal with a fetch error in react redux?
- what is the best way to use react router V6 navigation with redux and redux thunk actions?
- What is the correct way to React Hook Fetch Api and store to Redux and retrieve it with Selector immediately?
- What is the best way to store data with React Redux but by condition?
- What is the best way to access redux store outside a react component?
- What is the best way to implement undo state change (undo store/history implementation) in React Redux
- What is the best way to do Error Handling in React Native App.
- What's the best way to deal with an error in the server side and in the client side using nodejs + express
- What is the best way for connecting Django models choice fields with React js select options
- What the best way to loading data to a cart react js with context api
- What is the best way to trigger an redux action if the props changed after the react 16.3?
- What is the proper way to fetch JSON in React with Hooks?
- What's the best way to deal with an error about an unmounted component? Trying to implement CKEditor but get this error
- With React what is the best way to handle conditional classes
- React js, What is the best way to store redux state into local state?
- What is the best way to connect React js app with node js server?
- What is the best way to update item in React Redux
- What is the best way to define "KEY" in React when creating a list with map function from an array which containing no unique ID or fields?
- What is the best way of keeping database in sync with the Redux store (redux middleware)?
- What is the best way to build multi-language app with react and redux?
- React.JS What is the best way to deal with an undefined prop
- What is the best way to switch between web app's themes with React & Redux?
- What is the BEST way to do the error handling in react using Axios?
- What's the best way to replace image with default image on error in React JS
- What is the best way to redirect a page using React Router?
- What is the best way to trigger onchange event in react js
- React + Redux - What's the best way to handle CRUD in a form component?
- React - What is the best way to handle login and authentication?
- what's the best way to deal with undefined props in react.js?
- What is the proper way to use React Memo with Flow?
More Query from same tag
- reactstrap alert automatic hidden
- React-native define component height with flexbox
- how to do dynamic routing in child component in reactjs?
- How to have custom colors as props with mui v5 react typescript?
- What is the best way to set object properties when filling a complex form in React
- I want to remove the paypal paying button if user has select cash on delivery
- React HTML Editor (TinyMce)
- React Error Boundaries not working properly with async function
- How to test axios get request function in jest/enzyme tests?
- TypeScript with redux-thunk and axios
- Multiple dropdown menu state
- distinction between "() => (" and "() => {"
- Dynamically changing favicon in react.js
- How to reduce the number of product visible on my react carousel?
- Recompose pure() vs React.PureComponent
- react-dnd DragSource that has child DragSource
- Attempt to render state value from ajax call in componentDidMount failing (React)
- displaying alert to all the private route when user non logged in user tries to visit private route
- Share complex React app/component between single-page app, VScode web extension and JupyterLab extension
- TypeScript says a null value isn't assignable but I already check for nullability
- next.js bundle analyzer isn't creating pages to vew bundles
- Can only update a mounted or mounting component.
- Next.js form components wont allow to be edited once I give a value
- Warning: validateDOMNesting(...): <form> cannot appear as a descendant of <form>
- how to resolve useEffect eslint dependency warning?
- Webpack loading SVG with white border
- Error when getting values from json to data table
- React Render List Incorrect (List is correct, but render overwrite and duplicate)
- Ant Design, how to customize Steps component
- Can I call react component in a react component