Я расскажу, как я создал приложение для создания заметок с вложенными маршрутами, используя хуки react-router-dom и react-router.

Недавно я написал несколько сообщений в блоге о реализации react-router для создания вложенных маршрутов в приложении для создания заметок. Поскольку в то время я все еще работал над пониманием того, как работает react-router, я хотел написать новый итоговый пост, в котором более четко изложено, как я реализовал react-router в этом приложении.

В этих предыдущих сообщениях есть несколько приличных замечаний, но я думаю, что этот пост должен быть наиболее полным и последовательным, поскольку приложение наконец-то готово и развернуто. Вы можете посмотреть демо здесь: Chromatic Notes и код здесь на Github.

Это структура приложения, иерархия компонентов. Для того, чтобы четко запомнить для себя, как все это связано в будущем, и, надеюсь, чтобы помочь любому читателю лучше понять, я наложил на иерархию компонентов отношения маршрутизации между компонентами. Есть те компоненты, которые содержат ссылки реактивного маршрутизатора, и другие компоненты, которые содержат маршруты реактивного маршрутизатора, которые обертывают дочерние компоненты.

Дочерние элементы маршрута отображаются, когда свойство пути маршрута соответствует URL-адресу в адресной строке. URL-адрес адресной строки изменяется при нажатии на ссылку, которая, как мне кажется, просто возвращает простой HTML-тег ‹a›.

Помните, что ссылка срабатывает первой, маршрут реагирует и отображает дочерний элемент.

Эта диаграмма довольно абстрактна. Я думаю, что легче понять маршрутизацию, взглянув на фактический пользовательский интерфейс приложения, а затем попеременно глядя на него и на диаграмму.

Выше вы можете увидеть основные компоненты, несущие ссылку, которые на самом деле представляют собой наборы компонентов, созданные путем преобразования массивов в компоненты React. Коллекция слева представляет собой сетку, а справа у нас есть список. С левой стороны, если щелкнуть темно-зеленую карточку NotebookCard, справа отобразится темно-зеленая таблица содержания.

Как это произошло?

В App.js мы сопоставляем массив блокнотов для создания левой сетки, преобразуя каждый блокнот POJO (простой старый объект JS) в компонент NotebookCard. Сама NotebookCard имеет компонент Link реакции-маршрутизатора, чья реквизита «to» указывает на URL-адрес, который соответствует компоненту TableOfContents определенного цвета (или, если быть точным, URL-адрес соответствует реквизиту пути маршрута, содержащего конкретный TableOfContents). компонент). Эта ссылка выглядит так: ‹Link to={`/${props.color}`} ›

В App.js мы также сопоставляем тот же массив блокнотов, чтобы создать компонент маршрута для каждого блокнота; каждый из этих компонентов Route является оболочкой компонента TableOfContents, и каждый Route имеет свойство path, указывающее на значение пути, использующее свойство цвета записной книжки в качестве уникального идентификатора, например: path={`/${notebook.color}`}

Этот шаблон повторяется, но становится немного сложнее на следующем уровне, где мы глубже вкладываемся в приложение. В компоненте TableOfContents вместо сопоставления массива записных книжек мы сопоставляем массив заметок каждой записной книжки для создания двух типов дочерних компонентов: 1) список карт NotePreviewCard, содержащих ссылки, которые будут заполнять TableOfContents, а также список компонентов NotePage. , каждый из которых заключен в маршрут, который будет отображать NotePage и заменять компонент TableOfContents на экране при нажатии ссылки ( 📖 ) в NotePreviewCard.

Итак помните, что сначала срабатывает ссылка, затем маршрут реагирует и отображает дочерний элемент.

Что здесь немного сложнее, так это то, что, поскольку мы вложены друг в друга, теперь нам нужно продолжать добавлять уникальные идентификаторы к другим уникальным идентификаторам в наших ссылках и маршрутах. Нам либо нужно передать routerProps компонентам, которым это нужно, либо вместо этого мы можем использовать хуки react-router.

Что хорошо в использовании хуков react-router, так это то, что это освобождает нас от необходимости прописывать routerProps, а скорее в компоненте, которому нужен доступ к routerProps, мы можем просто вызывать хуки, такие как useRouteMatch и useParams.

Это именно то, что я сделал внутри NotePreviewCard, которому необходимо получить доступ к свойству URL, чтобы передать его в качестве опоры для своей ссылки. Поскольку NotePreviewCard сам по себе не является маршрутом, я не знаю хорошего способа получить его routerProps, кроме как передать routerProps из родительского компонента, визуализируемого маршрутом, т. е. просверлить пропс.

Чтобы уточнить, для компонента NotePage, поскольку он обрабатывается компонентом маршрута, у нас, естественно, есть доступ к routerProps путем рендеринга компонента NotePage внутри свойства рендеринга маршрута.

Вы можете увидеть разницу здесь:

После слияния routerProps с реквизитами NotePage, если я запишу реквизиты console.log в компоненте NotePage, вы увидите, что в его реквизитах у меня есть доступ ко всем ключам объекта routerProps, то есть к истории, местоположению и объектам соответствия.

Поскольку у меня нет доступа к routerProps в NotePreviewCard, так как он не обернут маршрутом, мне пришлось бы использовать сверление пропсов, чтобы объединить routerProps в его собственные пропсы. Вместо этого я могу просто вызвать хук react-router внутри NotePreviewCard и таким образом безошибочно получить доступ именно к той части информации из routerProps, которая мне нужна, вместо того, чтобы получать весь объект.

URL-адреса идут с компонентами Link, поэтому в NotePreviewCard я вызываю useRouteMatch и извлекаю ключ URL-адреса из объекта сопоставления.

При этом я создаю правильную ссылку, добавляя props.id (уникальный идентификатор заметки) к URL-адресу (уникальный идентификатор для TableOfContents, например, «темно-зеленый»). Результирующий объединенный URL-адрес будет выглядеть как «/dark -зеленый/33” или “/голубой/2”.

При нажатии на эту ссылку URL-адрес адресной строки изменяется, и соответствующий маршрут отображает свой дочерний компонент NotePage с правой стороны:

Полезные ресурсы: Вложенные маршруты с React Router v5