Advanced Remix Non-Nav Mutations Solution
Transcript from the "Non-Nav Mutations Solution" Lesson
>> That was hopefully for most of you, maybe a letdown in the amount of effort it took. So we're gonna say exercise one and go to the invoice ID because literally all you had to do is change like three lines of code four maybe, so we need to use the use fetcher API from Remix.
[00:00:23] So we'll get a Fetcher. We can call this something descriptive because you can use more than one fetcher in a component. And so I'm going to call this our depositFetcher. Maybe we'll call it the new DepositFetcher to be even more clear. And we're gonna say, use Fetcher from Remix run React.
[00:00:43] And the new deposit fetcher has a handy little form component on it that is actually very similar to the global form that you can import from remix. The only difference is that this one does not trigger a navigation. So no entry in the history stack. That's it. That is so you're like, okay, what do I use the regular form versus a fetcher form?
[00:01:07] That is it. If you don't want it to be another entry in the history stack, then you use the regular or then you use the fetcher form. And, yeah, that's it. We're done. So if we come over here and I will just open up a brand new thing, there's no entries in the history stack.
[00:01:24] And I submit another $25 today. And we will see we still have no entries in the history. So this is for favoriting your tweet, for deleting the deposit for like, in fact, let's delete this deposit because that's a lot of money and I want to see more yellow there.
[00:01:41] So we'll delete that. And that was a fetcher. And that is it. Any questions about this? Yeah.
>> Just maybe a fun thing to expand on. Is there a good way to clear those values after you submit or just use normal?
>> Yeah, great question. So yes, I actually didn't call that out and I should have we hit Create and those values are still there certainly not desired.
[00:02:10] The reason that it works before this is because we're changing our location and triggers a rerender. And I believe we've got a key prop yeah right here that has the key based on location. So anytime the location changes that will trigger a rerender here and the reason that's useful is that as you switch between these different users it updates all of this content.
[00:02:34] That actually doesn't matter for these things. They will update for sure. It's just an anything that's maintaining state internally, if it's not remounted, will maintain that old state. So that's why we have the key prop with the location key you don't always need to do that. But yeah so, that's why it was working before because we're actually, it's a new location even though it's the same URL.
[00:02:56] It's technically a new location and now we don't have that now. The location is the same and so we're not clearing out the form so the solution to that is actually in upcoming exercises so great question
>> How do we decide between use fetter and use fetchers?
>> Okay yeah use fetchers is another.
[00:03:17] We will not be getting into that today, but what useFectors does is it gets you a list of all fetchers. So all of the fetchers everywhere in the application will be in this list so any anytime any other component calls useFetcher it's creating a new fetcher and that will show up in this list here?
[00:03:40] This is useful for actually let's see, if I want to, I'll show an app later when we start talking about optimistic UI that uses use fetchers quite a bit. It can be useful for optimistic UI in particular. I think that's probably its primary use. But yeah, we're not gonna be using it today.
[00:04:03] It's more for collecting existing fetchers rather than creating. So useFetcher, will create a fetcher for you. Cool, any other questions? Yeah, true.
>> I guess a general question is to help with like the understanding of it is like to me it seems like it's not really. Like when you use useFtcher.form it's not really any different on the server side is it more.
[00:04:31] I guess like how's it working I'm just kidding
>> Yeah so as far as the the network request is concerned is the request will be the same. So, if we say here's my amount? Here's my day? And I hit create this post request so, it's still gonna be a form data all of the same things apply and so, yeah, we didn't need to change our back end code it'll be the same.
[00:04:56] The one thing to to note about this though is that if you're switching from a regular form to a form that doesn't have or to a fetcher form normally your back end code is gonna do a redirect. Because that's like how you probably set it up initially. And so it'll like redirect to the same place.
[00:05:20] So that is one thing you may need to change if you're doing this switch is just make sure that you're not doing a redirect from a fetcher. Unless that's what you wanna do. Like let's say that you say, somebody tries to do fetcher, but they timed out in their login or something.
[00:05:34] So now you're gonna redirect them. So they're like it's not bad to redirect from a fetcher action but yeah, typically what I do I just return a response okay, and it's fine.
[00:06:26] If Twitter had written their like button with useFetcher your likes would still work and just be super annoying because it's gonna do a full page refresh but still totally works.
>> That's probably why it's important to have the invoice invoice ID in the in the URL, because it was doing a full page refresh and you didn't have that you just go like to the top
>> Are we avoiding mutations outside of forms entirely?
>> Most of the time your user interactive mutations should be forms. I would say probably all the time no, not all the time there are exceptions of course.
[00:07:24] But the vast majority of the time if the user is interacting and triggering a mutation that should have be modeled as a form for progressive enhancement reasons. And also it's just like a way simpler way to do it. But we'll see you later in the exercises today that and you have plenty of situations where the initiating mutation and we can do that imperatively.
[00:07:49] We would use useFetcher for that as well, but when we get that you can find out how do we do that?
>> Like button in a form.
>> Yes, I would exactly. Yep in fact, if you look at the deposits I said earlier that this was a fetcher.
[00:08:07] But it's actually not because we will redirect from this deposits to just the deposits page. So that's not a fetcher. But even this Delete button is inside of a form. So, gone are the days where you just render a delete that has an on click. Yeah you don't need that anymore it's just a submit button this it's progressively enhanced it's like dang simple there's no event management or whatever.
[00:08:37] Yeah, you will prefer this. Even though it may be a little different, it was different for me to think yeah, I guess I can just put a form around that thing. Cool yeah.
>> I have one more question. How does remix know what routes to revalidate after submitting the form example?
>> Good questions. So remix re validates everything, all current routes that are active on the page or if you redirected then it's not rebounded, it's just loading all those. But if you redirected within it, you've got a parents and you have a child and you're redirecting between siblings.
[00:09:16] And then the parent will actually also revalidate. So yes the way that the web works or the defaults of the web is you submit a form you're getting all brand new HTML open HTML to closing like the whole thing is new. So remix emulates that same behavior which is correct, that's the right thing to do.
[00:09:34] And in some cases, it may not be optimal, which is where optimizations come in. So the default is right, optimizations are possible, and we will get into that later yeah.
>> How do you useFetcher to fetch data not associated with UI routes?
>> We will actually get into that.
[00:09:57] Yep for sure. When we build this Create Invoice Customer thing as we were typing in here that's not associated to UI routes. That's just a component and we will get into that.
>> What if we have a postcode and another route when using useFetcher other than the current route?
[00:10:17] We need an action prop in the fetcher, right? But how do we construct the path so that it hits the correctly desired route?
>> Yeah, good question. So we can provide an action prompt to this. And this action will need to point to a route somewhere that can accept that action.
[00:10:33] So you'd say like api/ yeah, that works except you want to put in the actual Invoice ID so stringfy that thing whatever. But yes that is totally possible and you'll just need to create a resource route at that path in your file system to handle that. We will sort of touch on this later.
[00:10:57] Most of the time I find that I don't use the action prop most of the time. It's just easier to have it in the same file. But there are certainly some situations where and we're rendering this component in a bunch of different places. All of them we want to go to this specific route.
[00:11:11] We will talk about that a little bit, not with the fetcher form. But with a different thing that you can use with the fetcher.