Complete Intro to React, v7 Error Boundaries Q&A
This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Error Boundaries Q&A" Lesson
>> We're using componentDidUpdate here for the first time that you've seen it. But you'll use this all the time, this is not specific to, Error boundaries, right? This can be used in any class component. You can kinda think of this like a useEffect that's dependent on something, right?
[00:00:21] So we used one in useReadList, right? This is basically like, this useEffect here is basically componentDidUpdate that only responds to animal, right? So anytime that animal changes, this effect gets run. It's pretty similar, not totally the same here with componentDidUpdate. This is just basically a useEffect that responds to any state change.
[00:00:49] And then you just have to check to make sure that you're responding to the correct state change. The big difference here is componentDidUpdate doesn't run at start, right? Whereas useEffect, no matter what you're responding to will always run at the beginning. That's the hair to split there. Yeah.
>> It's time to clarify how it's all working. So the error occurs which causes the component to update, then we get to that conditional which would be true. The timer starts off, then we hit the setState, which gives us redirect true. And then does the state updating cause the render function to be called again?
>> It does.
>> And that's why-
>> Correct, every time that you call setState, you can guarantee that a rerender's gonna happen.
>> You mentioned just a second ago, we can think of componentDidUpdate as a useEffect that responds to any state change. Is that specifically any state change for this component then?
>> It only cares about its own state, it cares about no parent nor child state, just its own state. Yeah, just for funsies, let's just walk through the entire lifecycle of what happens in this damn component. All right, so we're in details. We hit our hilarious error here, right?
[00:02:17] This is going to throw an error which is going to crash. You can see my linter is very upset that this is unreachable code. It's going to hit WrappedDetails which is gonna hit this ErrorBoundary. This ErrorBoundary component does have a component, or not a componentDidCatch. We actually could just leave this out totally, all this is doing is reporting.
[00:02:38] So it's actually gonna call this function here, getDerivedStateFromError. Which is going to rerender this again, but it's going to return this new state. This is basically calling setState on a crash state, right? So this is going to rerender again with this hasError, which does this, right? It renders, right?
[00:02:59] And the first time it does have an error, but does not have redirect, right? So it's going to call this and we're going to hit this block here, right, cuz it has an error. It's also going to call componentDidUpdate. And this error, it does have an error this time, so it's gonna set a timeout for in 5,000 milliseconds to call this.setState with redirect true.
[00:03:28] Once you call setState again it's going to rerender again and it's gonna hit this block, which is gonna cause it to navigate to the homepage. Now mind you, typically if this was not navigating, it would've called componentDidUpdate again, but it's gonna unrender itself before that happens. Okay, does that makes sense?
[00:03:52] It's a bit convoluted, not something you have to do very frequently with React, it's kind of an advanced use case. But it's good for you to kinda see how all the component lifecycle methods can interact with each other. All right, cool. Questions about error boundaries? We've now hit ten dash error boundaries, if you wanna catch up there.
>> Could you please explain again, I just noticed on line 27 there's that, it's in curly brackets, the empty string again, yeah. And you have that as well in your demo, but it's right after the link tag. Can you remind me what that's doing?
>> Yeah, This is Prettier specifically that's doing this.
[00:04:35] So Prettier tries to keep your line length relatively tame, right? There's some people that are super bent over or bent out of shape about I need 80 characters on this line, if it's 81 then I lose my mind, right? So what Prettier in general tries to do and tries to be reasonable about as it tries to put 80-ish characters per line, or 120, I don't remember exactly what that character.
[00:05:24] All it's doing here is it's adding a space. But it's doing that explicitly so that there's a space between the link and JK period, right? I think this would work, right, you could just put the space here. And that should work, and in any case, I just tend to ignore it because it's Prettier putting it in there and the net result is the same thing.
>> Thank you.
>> Mm-hm, actually you can see there, it took the space out. Whereas if we put the space here like that, The space is back in. So I've never really dug into it enough to really find out why it does that. But it's the finicky nature of it, it's just trying to put a space there cuz you asked it to.
>> Is it safe to assume that getDerivedStateFromError access setState for us passing to it it's return value as an arg?
>> Yeah, so I think the question is, you're returning an object here, is it safe to assume that this gets passed directly to a setState call instead of React?
[00:06:43] I haven't dug into the code to know precisely the methodology that it does it. But functionally and pragmatically, yes, you can make that assumption in your head. I've never seen that vary in behavior. Whatever you return here is basically functionally calling setState with whatever object you have here.
[00:07:03] But I haven't shown you this, but you can actually call setState with a function. And there's some people that prefer that whatever you return the function gets passed into setState. There's some reason that people like doing that, and I cannot remember off the top of my head. For example, here I do not know if you can pass a function in here.
[00:07:23] I don't know if that works, I haven't tried. I guess we could just try and see if it works.
>> Is there a way to prevent useEffect from running when the component mounts for the first time?
>> Not off the top of my head.
>> Would that be an appropriate time to use componentDidUpdate or am I'm misunderstanding how it is?.
>> Well, the question is, in a function component, can you prevent useEffect from running? What you would do, the way I would do it is you would just put an if statement there. If this is the first time running, then don't execute whatever I don't want to execute.
[00:08:07] But I don't think there's a methodology for preventing it from running and just running on updates, not off top my head, anyway.