Step 19: Navigation

Let’s update the code so when navigate to Edit view we click on edit icon or “add note” button. (We will reuse the same page for adding/editing notes.) Moreover, we should return to the homepage when we click on the “cancel” or “save” buttons in the “edit” page.

pages/Edit.jsx
  import { Button, Container, Group, Stack } from "@mantine/core";
  import { TextInput, Textarea } from "@mantine/core";
  import { useState } from "react";
+ import { useNavigate } from "react-router-dom";
	
  function Edit() {
    const [title, setTitle] = useState("");
    const [text, setText] = useState("");
+   const navigate = useNavigate();
	
    const handleTitleChange = (event) => {
      setTitle(event.target.value);
    };
	
    const handleTextChange = (event) => {
      setText(event.target.value);
    };
	
    const handleSave = () => {
      console.log({ title, text });
+     navigate("/", { replace: true });
    };
	
    const handleCancel = () => {
      console.log("cancel");
+     navigate("/", { replace: true });
    };
	
    return (
      <Container>
        <Stack spacing="lg">
          <TextInput
            placeholder="Your note's title"
            label="Title"
            withAsterisk
            value={title}
            onChange={handleTitleChange}
          />
          <Textarea
            placeholder="Your note's text"
            label="Text"
            withAsterisk
            autosize
            minRows={5}
            value={text}
            onChange={handleTextChange}
          />
          <Group position="center" spacing="xl" grow>
            <Button variant="subtle" onClick={handleCancel}>
              Cancel
            </Button>
            <Button variant="default" onClick={handleSave}>
              Save
            </Button>
          </Group>
        </Stack>
      </Container>
    );
  }
	
  export default Edit;
components/Header.jsx
  import { IconNote } from "@tabler/icons";
  import { Grid, Button } from "@mantine/core";
  import Search from "./Search";
  import PropTypes from "prop-types";
+ import { useNavigate } from "react-router-dom";
	
  function Header(props) {
    const { query, setQuery, add } = props;
+   const navigate = useNavigate();
	
    const handleOnClick = () => {
      add();
+     navigate("/edit");
    };
	
    return (
      <Grid>
        <Grid.Col span={10}>
          <Search query={query} setQuery={setQuery} />
        </Grid.Col>
        <Grid.Col span={2}>
          <Button
            onClick={handleOnClick}
            fullWidth
            variant="default"
            leftIcon={<IconNote />}
          >
            Add Note
          </Button>
        </Grid.Col>
      </Grid>
    );
  }
	
  export default Header;
	
  Header.propTypes = {
    query: PropTypes.string,
    setQuery: PropTypes.func,
    add: PropTypes.func,
  };
components/NoteControl.jsx
  import PropTypes from "prop-types";
  import { Accordion, ActionIcon, Box } from "@mantine/core";
  import { IconTrashX, IconPencil } from "@tabler/icons";
+ import { useNavigate } from "react-router-dom";
	
  function NoteControl(props) {
    const { note, remove } = props;
    const { id, title } = note;
+   const navigate = useNavigate();
	
    const handleOnEdit = () => {
+     navigate("/edit");
    };
	
    const handleOnRemove = () => { 
      remove(id);
    };
	
    return (
      <Box sx={{ display: "flex", alignItems: "center" }}>
        <Accordion.Control>{title}</Accordion.Control>
        <ActionIcon onClick={handleOnEdit} size="lg">
          <IconPencil size={16} />
        </ActionIcon>
        <ActionIcon onClick={handleOnRemove} size="lg">
          <IconTrashX size={16} />
        </ActionIcon>
      </Box>
    );
  }
	
  export default NoteControl;
	
  NoteControl.propTypes = {
    remove: PropTypes.func.isRequired,
    note: PropTypes.shape({
      title: PropTypes.string.isRequired,
      text: PropTypes.string.isRequired,
    }),
  };

Notice in all the these cases, we used the useNavigate hook for navigation.

The useNavigate hook returns a function that lets you navigate programmatically.

Observe the app’s behaviour in the browser!