‫Next up,
‫let's learn about programmatic navigation
‫with the use navigate custom hook.
‫So programmatic navigation basically means
‫to move to a new URL
‫without the user having to click on any link.
‫And a common use case of this behavior
‫is right after submitting a form.
‫So many times when the user submits a form,
‫we want them to move to a new page
‫in our application automatically.
‫So without having to click on any link.
‫And so then we can use programmatic navigation
‫to achieve that.
‫So I'm sure you have seen that many times in action
‫in some web applications that you have used.
‫And so now let's do something like this here on our own.
‫Now in this example, what I want to do
‫is that whenever the user clicks somewhere here
‫in this map container,
‫we then want to move automatically here
‫to the form component.
‫So this is not the use case
‫that I explained in the beginning,
‫so after submitting a form,
‫because by now we don't have any form yet
‫but we will do that later.
‫But for now, let's just implement what I just said.
‫So clicking here will then move right here
‫to the form component.
‫And clicking here cannot really happen with a link.
‫And so that's why we need programmatic navigation.
‫But first of all, let's set up our route correctly.
‫So right here we have form already
‫so we have our nested form route.
‫But now here we actually want to include the form component.
‫And this form actually has been giving to us
‫already in the starter data.
‫So we already have that in our files.
‫Let's just make sure that it has been included,
‫and well, actually, this is not the one that we want.
‫So it included this one from React Router Dom,
‫but we want our own one.
‫So form,
‫and so that's this one right here.
‫So you see it already has all the input fields
‫even linked up with the state here
‫so that we don't have to do that manually again
‫because at this point we already know how that works.
‫And so let's see,
‫yeah, this is now correctly linked.
‫And so if we come back here,
‫and then type form,
‫let's see,
‫and beautiful.
‫So here we have our form,
‫but at this point we have no way of moving to this URL.
‫And so again, we now want that to happen
‫when the user clicks somewhere on the map here.
‫So let's do that.
‫And so let's attach an event handler here on click.
‫Add then here our function.
‫Okay.
‫And we will finish this function later
‫because before we can keep going,
‫we now need to actually use the use navigate hook.
‫So another hook that is provided by React Router,
‫so use navigate,
‫and all this one does
‫is to return a function called navigate like this.
‫And so then we can use this function here
‫to basically move to any URL.
‫So we just need to call that here.
‫And so let's say we want to move to the form and that's it.
‫So let's go somewhere else.
‫At least it should be here in the app.
‫And so now let's see what happens
‫when I click somewhere here.
‫And indeed, it did move to the form.
‫So without us having to click on any link.
‫So this is programmatic navigation
‫where we basically in an imperative way
‫navigate to this URL.
‫So here, in enough, we do that also.
‫So we also navigate to another page,
‫but in a declarative way
‫because we just declare this component in our JSX
‫and that will then do the work
‫of navigating to the city's URL for us.
‫But in this case, again, we do it in an imperative way
‫because we cannot use the link in this situation.
‫And the same again after submitting a form.
‫So then we would have to also call this navigate function.
‫And so we will do that later.
‫So this is one use case of the navigate function
‫but we can also do something else
‫which is to simply navigate back,
‫which is in fact something
‫that we cannot do just with links.
‫So let's try that out by coming here to the form.
‫And so here we actually have a button to go back.
‫And so now we want to implement that functionality.
‫But before we do that,
‫I now want to create actually a reusable button component.
‫So let's create a new file here,
‫button.JSX.
‫And here it is now a button element.
‫And then let's see what we need here as props.
‫So we need the children prop
‫so that we can pass in some content.
‫Then, we also need to accept the on click prop.
‫And finally, here, I also want to accept a type string.
‫And so using that type,
‫I then want to conditionally add a CSS class.
‫But let me show that to you in the end.
‫So first, let's do our typical things,
‫which is to allow the user
‫to attach an on click event handler to this button.
‫Okay.
‫Then we also need to get in our styles.
‫And then let's add the class name here,
‫styles.btn.
‫Okay.
‫So let's come back here and use that button.
‫And for now, we don't pass in here
‫the on click event handler as we will do that later.
‫So here we got some styling already, but that is not enough.
‫So let's come here to the CSS module for the button.
‫And notice that besides the button class,
‫we have these three other classes.
‫And so now we want to allow the user
‫to pass in a type which can be either primary
‫or back or position.
‫And then according to that,
‫we will add the corresponding class.
‫So what I mean is this.
‫So instead of now manually passing in here a class name,
‫we just pass in a string
‫with the type of button that we want.
‫So here we want a primary button.
‫And so then, here we receive that
‫inside the button as the type,
‫and then we will use that as a class name here.
‫So, this means that now we need to add two class names.
‫And the way we do that in CSS modules
‫is that we need to create a template literal.
‫So let's wrap this first in back ticks,
‫then into this curly braces.
‫And then here, let's do the other one.
‫So for example, here we could say now styles.primary
‫and to then all the buttons would get green like this,
‫because the primary is the one with the green background.
‫But remember that actually here we want the type.
‫And so, here we now need to do it like this.
‫And so, here we get indeed the primary type
‫but if we use now the back button,
‫so let's do that,
‫then we will get another style.
‫So type now back,
‫and then let's see what we get.
‫And beautiful.
‫So we basically dynamically now
‫selected the style that we want using this type prop string.
‫So let's close that.
‫And now finally, let's attach the on click handler here
‫so that we can again
‫use the navigate function right here now.
‫So let's include our custom hook again.
‫So use navigate from React Router Dom.
‫And by the way, this used to be called use history
‫in a previous version of React Router.
‫And so now we want to navigate back.
‫So how do we do that?
‫Well, we just need to define basically
‫the number of steps that we want to go back
‫in the browser's history.
‫So if we say minus one,
‫then that means that we basically navigate back.
‫So let's try that out here,
‫and moving to cities,
‫And then as I click here, that will open the form.
‫And so now when I click here, we should move back to cities.
‫Right?
‫Well, that didn't really work.
‫I mean, maybe you saw a flash of this moving back
‫but then it reloaded the page here again.
‫And so the reason for that
‫is that this button is located inside a form.
‫So we are inside a form.
‫And so therefore,
‫this will trigger the form to be submitted.
‫And so that will then cause the page to reload.
‫So what we also need to do here is to prevent default.
‫So we need to receive the event,
‫and then we need to do e.prevent default.
‫And so this will then prevent this button as it is clicked
‫to submit this form.
‫So let's try that again.
‫Clicking here will open this.
‫And now as we move back, we are back here in is URL.
‫And if I go to countries,
‫then click here again, and click back,
‫then we move back to countries.
‫And of course, we could also move forward
‫by doing plus one here,
‫or we could move back twice by doing minus two.
‫But usually, what we always need is just like this.
‫Now okay, and that's actually it.
‫That is programmatic navigation for you.
‫Now here, I'm just noticing we have some problem.
‫So something with the country list.
‫So country list,
‫I remember that we removed the key from here,
‫but we never put it back.
‫So let's just use the country.country
‫which is unique in this situation.
‫So let's reload and then we get no more error.