In a Redux/React application I used the lifecycle method componentDidCatch() to catch and handle errors during rendering of the React UI. Is there a way to automatically notify the Redux store of the errors caught there, without necessarily dispatching an action?
You would definitely need to dispatch an action, but you can write an error filter around your top level component. For example let's say your entire app is wrapped in a <Home> app tag. In your home component you can use your componentDidCatch to send your errors to redux just one time for your entire project (because React will bubble the exception to the top level). The granularity in which you utilize componentDidCatch or Error Boundaries is up to you, but at a minimum...a single handler with a single dispatch at the top level should suffice.
Related
We know that if a Redux action triggers an API call to a server (whether in Redux middleware or Redux Thunk), it takes time to receive the answer from the server. During this waiting phase, the UI must somehow shows the user that some loading is being done (showing an Spinner for example). In React and React native, a famous trick to handle these common situations is a isLoading boolean flag in the Redux state and of course, a loading action being dispatched. This boolean will be toggled once the answer is ready to be shown, so that I can update the UI.
However, after applying this trick for years, what I've got is an application full of bugs and errors and a super dirty code with a lot of redundant code.
I have checked all the React life cycle hooks to check the order, in which the hooks are called and the process of Redux dispatching. It seems that Redux and React works totally separately. (I know that getDerivedStateFromProps is called once the store has been updated, but it does not solve my problem)
I need a better way to handle these common situations. I don't know if I need to make modification in Redux part of my application, or in the UI, or ...
I'm new to React and I'm trying to figure out the best way to request information from the server based on the URL. I'm using Redux and React Router v4.
Let's say I have a route /foo/:id, and a component Foo that will render something based on id. However Foo needs some server data related to id to do so. I believe the way to accomplish this would be to use mapDispatchToProps to create a function that takes id as input, does some async work, dispatches an action, and ultimately updates the redux state.
My question is: where is the most appropriate place to invoke the dispatch? In this scenario, there's no form submission or button click to kick things off. Originally I was thinking of including a check for the id data in render() and fetching if it was not populated, but this felt wrong due to the side effects.
You can do it in componentDidMount of the Foo component, similar to this example from the Redux GitHub project.
Your intuition is right that render is not a good place to do so. Most people do it in the componentDidMount lifecycle method of the component.
On a relevant note, you will also want to do fetching also in the componentWillReceiveProps method like what they did here. Reason being if your user navigated from foo/1/ to foo/2/, the component is already on the screen and will not be mounted again, hence componentDidMount will not be called again. The fetching for the second user will be done in the componentWillReceiveProps method.
i think the best way to do the dispatch inside the componentWillReceiveProps() which would help you fetch some data before the component renders
It seems your use case is well-captured by the react-refetch package which you can find here. It provides a higher-order component that allows you to specify dependencies at specific API endpoints and then resolves them when a new instance of your component is created.
Importantly it injects the data into your components props using a synchronous abstraction of a promise called a PromiseState. This will allow you to conditionally render your component depending on whether the data is say pending, fulfilled, rejected, etc.
This is not attached in any way to Redux, it skips that layer entirely, so do keep it in mind that the response is directly injected into the component and does not go through your redux store's state.
I've spent a bit of time recently trying to find a comprehensive and reliable way of handling errors in React for both sync and async operations. I'm using React 15.5.4 and TypeScript 2.4.1.
My goal is to catch errors in sync and async operations(lifecycle methods, event handlers) and display them in a ErrorDisplay component that is the closest parent of the component that triggered the error.
This is what I have tried but none of the solutions seem to cover all edge cases:
unstable_handleError as per https://github.com/facebook/react/issues/2461#issuecomment-311077975 handles only errors in render, does not handle errors in event handlers
custom batch updater as per https://engineering.classdojo.com/blog/2016/12/10/catching-react-errors/, works in production only, doesn't seem to work with event handlers
There is one more approach that I'm planning to try which is to wrap each method at runtime and use React context to pass information re where a given error needs to be displayed. I hesitate a bit to use this approach because React context API is still marked as experimental.
Thoughts?
I am currently building a React app which does a lot of server communication. If a server error occurs, I want to display the error to the user in a general way, e.g. an overlay with the error message.
Using container components
In my reducers, I return something like this:
{
type: "LIST_POSTS_ERROR",
loading: false,
error: {
msg: "An error occurred"
}
}
Obviously, my container components are redux aware. In the render() function, I could check, if the current state has a property error and if so, I would render the error message. Oddly, in every container component, I would have to check the current state and might have duplicated code in every container component.
A more general approach
What am I looking for is a more general approach. Something that knows about all the states and displays the error message automatically if the current state contains an error. Think of it like an interceptor for errors. Of course, this component would not belong to a route, so I am wondering if this is even possible?
How do you do error handling in your React app? I would love to know your approach!
In my app, I've a action called handleError which will trigger a toast component in my app.
You can dispatch this action at the time of error. Like, you can dispatch it in the .catch() of the Promise.
I am trying something similar for my App. So fire a dispatch on catch or >=400 response to set a string(your api response) in state and connect this value to your component.
Next, after maybe 4-5 seconds fire a dispatch to clear that value, so your message would go away. This you can implement in your login screens or your post API calls.
Hope it helps !!!
I am using react-router with the flux architecture (facebook's flux implementation).
Currently in my system I have route that says "chat/:topic".
When the user is entering this component, I am creating a subscription (using action creation, on componentWillMount) to a websocket server, and I am removing the subscription on componentWillUnmount.
When the user is moving to another route the whole workflow works alright - because react-router is unmounting my component.
When I transition inside my route (from "chat/games" to "chat/tv"), the component isn't mounted and I need to clear my state of the components.
I read about different actions that I can take and this on transition to dispatch an action "TRANSITION" and every relevant store will clear it's store.
In my opinion, this kind of action - is wrong, it couples my stores and my router.
How would you solve this problem? Is this an issue that I should raise to react-router and ask them to unmount inside my route?
I found the answer thanks to gaearon (https://github.com/gaearon/),
Use a store to keep the selected topic and ask the messages store for messages, in flux you shouldn't remove anything from your store, unless you need it for a performance reasons.
In my application, I must remove the messages (since they are large objects) and clear my subscriptions (to reduce the load on the server).
In order to achieve this there were three solutions that I found:
Use componentWillReceiveProps and check if the params are changed, if the params are changed - do whatever you need in order to clear the store - for example call ActionCreator and reset the state.
Send a dispose payload in transition (inside Router.run) which will tell all the stores to clear themselves.
last solution (which I used) making sure that my components are unmounted - Why? It is too error prone to clear the state on componentWillReceiveProps/dispose and it is clearer to just ensure the components are unmounted.
Details on how to achieve this:
https://github.com/rackt/react-router/issues/292
https://github.com/rackt/react-router/issues/496#issuecomment-64152941
I believe that compomentWillReceiveProps might solve your issue. This is what react router uses to pass stuff to you.
As far as I know, you need to use both componentWillReceiveProps AND componentDid/WillMount to catch the initial render also.
I'm anxiously awaiting the react-router 1.0 release (this weekend?) in hopes that there is a more elegant way to do this.