Как обновить react router dom
Перейти к содержимому

Как обновить react router dom

  • автор:

ReactDOM

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

import * as ReactDOM from 'react-dom';

Если вы используете ES5 с npm, можете написать:

var ReactDOM = require('react-dom');

Также react-dom предоставляет отдельные модули для клиентских и серверных приложений:

Пакет react-dom экспортирует следующие методы:

Следующие методы react-dom все еще экспортируются, но считаются устаревшими:

Примечание:

Методы render и hydrate были заменены на новые client методы в React 18. Эти методы будут предупреждать, что ваше приложение будет работать, словно используется версия React 17 (узнайте больше здесь).

React поддерживает все современные браузеры, хотя для более старых версий браузеров понадобятся полифилы.

Примечание

Мы не поддерживаем старые браузеры, в которых отсутствует поддержка ES5-методов или микротасков, например Internet Explorer. Возможно, вам удастся обойти эту проблему в старых браузерах, если вы подключите шимы es5-shim и es5-sham. Пожалуйста учтите, что этот путь официально не поддерживается и вы принимаете решение на свой страх и риск.

This content is out of date.

Read the new React documentation for createPortal .

createPortal(child, container)

This content is out of date.

Read the new React documentation for flushSync .

flushSync(callback)

Заставляет React произвести любые обновления внутри колбэка синхронно. При этом DOM обновляется сразу.

// Принудительно укажем, что данное обновление состояния должно быть синхронным. flushSync(() =>  setCount(count + 1); >); // К этому моменту DOM уже обновлен.

Примечание:

flushSync может сильно влиять на производительность. Используйте в редких случаях.

flushSync может заставить Suspense, которые ожидают содержимое, показывать их fallback состояние.

flushSync может вызывать ожидающие эффекты и синхронно применять любые их обновления перед возвратом.

flushSync может вызывать обновления вне колбэка, если это нужно для выполнения обновлений внутри колбэка. Например, если есть ожидающие обновления от клика, React может применить их до того, как применит обновления внутри колбэка.

This content is out of date.

Read the new React documentation for render .

render(element, container[, callback])

Примечание:

render был заменен на createRoot в React 18. Подробнее о createRoot.

Рендерит React-элемент в DOM-элемент, переданный в аргумент container и возвращает ссылку на компонент (или возвращает null для компонентов без состояния).

Если React-элемент уже был ранее отрендерен в container , то повторный вызов произведёт его обновление и изменит соответствующую часть DOM, чтобы она содержала последние изменения.

Если дополнительно был предоставлен колбэк, он будет вызван после того, как компонент отрендерится или обновится.

Примечание:

render() управляет содержимым передаваемого вами узла контейнера. Любые существующие элементы DOM внутри заменяются при первом вызове. Более поздние вызовы используют алгоритм отслеживания изменений React DOM для эффективного обновления.

render() не изменяет узел контейнера (изменяет только дочерние элементы контейнера). Если нужно, можно вставить компонент в существующий узел DOM без перезаписи существующих дочерних элементов.

render() в настоящее время возвращает ссылку на корневой экземпляр ReactComponent . Однако использование этого возвращаемого значения является устаревшим и этого следует избегать, потому что в будущих версиях React-компоненты могут отображаться асинхронно в некоторых случаях. Если вам нужна ссылка на корневой экземпляр ReactComponent , предпочтительным решением является прикрепить реф (ref) на колбэк к корневому элементу.

Использование render() для гидратации контейнера, отрендеренного на сервере, объявлено устаревшим. Вместо этого используйте hydrateRoot() .

This content is out of date.

Read the new React documentation for hydrate .

hydrate(element, container[, callback])

Примечание:

hydrate был заменён на hydrateRoot в React 18. Подробнее можно узнать в hydrateRoot.

То же, что и render() , но используется для гидратации контейнера, HTML-содержимое которого было отрендерено с помощью ReactDOMServer . React попытается присоединить обработчики событий к уже существующей разметке.

React ожидает, что отрендеренное содержимое идентично на сервере, и на клиенте. Текстовые различия в контенте могут быть переписаны поверх, но вам следует рассматривать такие нестыковки как ошибки и исправлять их. В режиме разработки React предупреждает о несоответствиях во время гидратации. Нет никаких гарантий, что различия атрибутов будут исправлены в случае несовпадений. Это важно по соображениям производительности, поскольку в большинстве приложений несоответствия встречаются редко, и поэтому проверка всей разметки будет непомерно дорогой.

Если атрибут отдельного элемента или текстовое содержимое неизбежно отличается на сервере и клиенте (например, отметка времени), вы можете отключить предупреждение, добавив к элементу suppressHydrationWarning= . Он работает только на один уровень в глубину, и задумана как лазейка. Не злоупотребляйте ею. Если это не текстовый контент, React по-прежнему не будет пытаться его исправить, поэтому он может оставаться несовместимым c обновлённым в будущем вариантом.

Если вам нужно намеренно отрендерить что-то другое на сервере и клиенте, вы можете выполнить двухпроходный рендеринг. Компоненты, которые рендерят что-то другое на клиенте, могут читать переменную состояния, такую как this.state.isClient , которую вы можете установить в true в componentDidMount() . Таким образом, начальный этап рендеринга будет отображать тот же контент, что и сервер, избегая несовпадений, но дополнительный этап будет происходить синхронно сразу после гидратации. Обратите внимание, что этот подход замедлит ваши компоненты, потому что они должны рендерится дважды, поэтому используйте его с осторожностью.

Не забывайте про работу с вашим приложением при медленных соединениях. JavaScript-код может загружаться значительно позже исходного HTML-рендеринга, поэтому, если вы рендерите что-то другое только для клиента, переход может вызвать раздражение. Тем не менее, при правильном выполнении может оказаться полезным отобразить «оболочку» приложения на сервере и показать только некоторые дополнительные виджеты на клиенте. Чтобы узнать, как это сделать без проблем с разметкой, обратитесь к объяснению в предыдущем абзаце.

This content is out of date.

Read the new React documentation for unmountComponentAtNode .

unmountComponentAtNode(container)

Примечание:

unmountComponentAtNode был заменён на root.unmount() в React 18. Подробнее можно узнать в createRoot.

Удаляет смонтированный компонент React из DOM и очищает его обработчики событий и состояние. Если в контейнер не было смонтировано ни одного компонента, вызов этой функции ничего не делает. Возвращает true , если компонент был размонтирован, и false если нет компонента для размонтирования.

This content is out of date.

Read the new React documentation for findDOMNode .

Примечание:

findDOMNode — это лазейка, используемая для доступа к базовому узлу DOM. В большинстве случаев использование этого метода не рекомендуется, поскольку он нарушает абстракцию компонента. Метод устарел в StrictMode .

findDOMNode(component)

Если этот компонент был смонтирован в DOM, он возвращает соответствующий DOM-элемент браузера. Этот метод полезен для чтения напрямую из DOM (например, чтение значений полей формы) или произведения измерений DOM. В большинстве случаев, вы можете присоединить реф к узлу DOM и полностью избежать использования findDOMNode .

Когда компонент рендерится в null или false , findDOMNode возвращает null . Когда компонент рендерится в строку, findDOMNode возвращает текстовый узел DOM, содержащий это значение. Начиная с React 16, компонент может возвращать фрагмент с несколькими дочерними элементами, и в этом случае findDOMNode возвращает DOM-узел, соответствующий первому непустому дочернему элементу.

Примечание:

findDOMNode работает только с смонтированными компонентами (то есть компонентами, которые были размещены в DOM). Если вы попытаетесь вызвать этот метод для компонента, который ещё не был смонтирован (например, вызовете findDOMNode() в методе render() для компонента, который ещё не был создан), будет сгенерировано исключение.

findDOMNode не может быть использован с функциональными компонентами.

Can I have compatibility issues with react and react-dom if I upgrade react-router-dom?

I created a web app and I’ve been learning react as I go. I created a react app with create react app command, and I’ve been working with these versions of react,react-dom and react-router-dom.

"react": "17.0.2", "react-dom": "17.0.2", "react-router-dom": "^5.3.4", 

These last two were installed automatically, and I don’t really understand how these interact, or if they do, even. I want to upgrade react-router-dom from v5.3.4 to v6, but I don’t know if by upgrading react-router-dom I will have compatibility issues with the other dependencies. Are these dependencies compatible with each other? As a bonus question, is there a place where I can see compatibility between different packages? I usually find this information by accident while reading StackOverflow answers to related questions in StackOverflow. Thanks!

asked Nov 30, 2022 at 22:22
109 2 2 silver badges 8 8 bronze badges

I recommend using version control such as Git. Then you can make these changes to test them out yourself. If it breaks, Git allows you to easily roll back to the version that works.

Dec 1, 2022 at 15:58

1 Answer 1

I want to upgrade react-router-dom from v5.3.4 to v6, but I don’t know if by upgrading react-router-dom I will have compatibility issues with the other dependencies.

Are these dependencies compatible with each other?

The only (recent) issue I’m aware of between react / react-dom and react-router-dom is between react@18 and react-router-dom versions below v5.3.3 and the app was being rendered into a React.StrictMode component. You can read a bit more about this in my answer here: Link tag inside BrowserRouter changes only the URL but doesn’t render the component. The problem is resolved in [email protected] and higher.

If you are sticking to react@17 there are no issues with react-router-dom , they work seamlessly without issue. If also upgrading to react@18 and using [email protected] or higher (i.e. v6) there are also no issues.

Is there a place where I can see compatibility between different packages?

Nothing I’m aware of, no. I think most issues are found organically and may be filed as issues in the various repos hosting the specific packages. If you find an issue with a library/package, then that repo’s issues tracker/section is likely where you want to start a search (other than Googling the issue, which may lead to stackoverflow posts or the repo issues directly).

Как обновить react router dom

v6.4 is our most exciting release yet with new data abstractions for reads, writes, and navigation hooks to easily keep your UI in sync with your data. The new feature overview will catch you up.

I’m New

Start with the tutorial. It will quickly introduce you to the primary features of React Router: from configuring routes, to loading and mutating data, to pending and optimistic UI.

I’m on v5

The migration guide will help you migrate incrementally and keep shipping along the way. Or, do it all in one yolo commit! Either way, we’ve got you covered to start using the new features right away.

I’m Stuck!

Running into a problem? Chances are you’re not the first! Explore common questions about React Router v6.

React Router DOM: How to handle routing in web apps

LogRocket’s Galileo AI watches every session, surfacing impactful user struggle and key behavior patterns.

Editor’s note: This React Router DOM tutorial was last updated on 11 August 2021. It may still contain information that is out of date.

React Router DOM Tutorial With Examples

We’ve covered React Router extensively, including how to use Hooks alongside and instead of React Router, how to use React Router with Redux, and other advanced use cases. But if you’re just starting out with React Router, all that might be too much to wrap your head around.

Not to worry. In this post, I’ll get you started with the basics of the web version, React Router DOM. We’ll cover the general concept of a router and how to set up and install React Router. We’ll also review the essential components of the framework and demonstrate how to build routes with parameters, like /messages/10 .

Here’s what you’ll learn:

  • What is a Router in React?
  • What is React Router?
  • What does React Router DOM do?
  • What is the difference between React Router and React Router DOM?
  • Installation
  • The React Router API: , , and
  • Understanding routes
  • Nested routes
  • How to set the default route in React

To demonstrate how React Router DOM works, we’ll create an example React app. You can find an interactive demo on CodeSandbox. For reference, the code of the final example is available on GitHub.

What is a router in React?

Single-page applications (SPAs) rewrite sections of a page rather than loading entire new pages from a server.

Twitter is a good example of this type of application. When you click on a tweet, only the tweet’s information is fetched from the server. The page does not fully reload:

These applications are easy to deploy and greatly improve the user experience. However, they also bring challenges.

One of them is browser history. Because the application is contained in a single page, it cannot rely on the browser’s forward/back buttons per se. It needs something else. Something that, according to the application’s state, changes the URL to push or replace URL history events within the browser. At the same time, it also needs to rebuild the application state from information contained within the URL.

On Twitter, for example, notice how the URL changes when a tweet is clicked:

And how a history entry is generated:

React Router DOM: Updating History in Twitter

This is the job of a router.

A router allows your application to navigate between different components, changing the browser URL, modifying the browser history, and keeping the UI state in sync.

What is React Router?

React is a popular library for building SPAs. However, as React focuses only on building user interfaces, it doesn’t have a built-in solution for routing.

React Router is the most popular routing library for React. It allows you define routes in the same declarative style:

But let’s not get ahead of ourselves. Let’s start by creating a sample project and setting up React Router.

I’m going to use Create React App to create a React app. You can install (or update) it with:

npm install -g create-react-app

You just need to have Node.js version 6 or superior installed.

Next, execute the following command:

create-react-app react-router-example

In this case, the directory react-router-example will be created. If you cd into it, you should see a structure similar to the following:

React Router DOM Directory

What does React Router DOM do?

React Router includes three main packages:

  • react-router , the core package for the router
  • react-router-dom , which contains the DOM bindings for React Router. In other words, the router components for websites
  • react-router-native , which contains the React Native bindings for React Router. In other words, the router components for an app development environment using React Native

React Router DOM enables you to implement dynamic routing in a web app. Unlike the traditional routing architecture in which the routing is handled in a configuration outside of a running app, React Router DOM facilitates component-based routing according to the needs of the app and platform.

React Router DOM is the most appropriate choice if you’re writing a React application that will run in the browser.

What is the difference between React Router and React Router DOM?

React Router is the core package for the router. React Router DOM contains DOM bindings and gives you access to React Router by default.

In other words, you don’t need to use React Router and React Router DOM together. If you find yourself using both, it’s OK to get rid of React Router since you already have it installed as a dependency within React Router DOM.

Over 200k developers use LogRocket to create better digital experiences

Learn more →

Note, however, that React Router DOM is only available on the browser, so you can only use it for web applications.

Can I use React Router DOM in React Native?

The react-router-native package enables you to use React Router in React Native apps. The package contains the React Native bindings for React Router.

Because React Router DOM is only for apps that run in a web browser, it is not an appropriate package to use in React Native apps. You would use react-router-native instead.

Installation

Because we are creating a web app, let’s install react-router-dom :

npm install — save react-router-dom

At this point, you can execute:

npm start

A browser window will open http://localhost:3000/ and you should see something like this:

React Router DOM Output

Now let’s create a simple SPA with React and React Router.

The React Router API: , , and

The React Router API is based on three components:

  • : The router that keeps the UI in sync with the URL
  • : Renders a navigation link
  • : Renders a UI component depending on the URL

In a web application, you have two options:

  • , which uses the HTML5 History API.
  • , which uses the hash portion of the URL (window.location.hash)

If you’re going to target older browsers that don’t support the HTML5 History API, you should stick with , which creates URLs with the following format:

http://localhost:3000/#/route/subroute

Otherwise, you can use , which creates URLs with the following format:

http://localhost:3000/route/subroute

I’ll use , so in src/index.js , I’m going to import this component from react-router-dom and use it to wrap the component:

import React from 'react'; // . import < BrowserRouter >from 'react-router-dom'; ReactDOM.render(   , document.getElementById('root') ); // .

It’s important to mention that a router component can only have one child element. For example, the following code:

// . ReactDOM.render(  
Another child!
, document.getElementById('root') ); // .

Throws this error message:

React Router DOM Error Messsage

The main job of a component is to create a history object to keep track of the location (URL). When the location changes because of a navigation action, the child component (in this case ) is re-rendered.

Most of the time, you’ll use a component to change the location.

Let’s create a navigation menu. Open src/App.css to add the following styles:

ul < list-style-type: none; padding: 0; >.menu ul < background-color: #222; margin: 0; >.menu li < font-family: sans-serif; font-size: 1.2em; line-height: 40px; height: 40px; border-bottom: 1px solid #888; >.menu a

In scr/App.js , replace the last

element in the render() function so it looks like this:

render() < return ( 
className="App-logo" alt="logo" />

Welcome to React

  • Home
  • Messages
  • About
); >

Don’t forget to import the component at the top of the file:

import < Link >from 'react-router-dom'

In the browser, you should see something like this:

Example» width=»720″ height=»272″>

As you can see, this JSX code:

Generates the following HTML code:

However, those aren’t regular anchor elements. They change the URL without refreshing the page. Test it.

Do you notice the difference?

Right now, the URL changes when a link is clicked, but not the UI. Let’s fix that.

I’m going to create three components for each route. First, src/component/Home.js for the route / :

import React from 'react'; const Home = () => ( 

Home

My Home page!
); export default Home;

Then, src/component/Messages.js for the route /messages :

import React from 'react'; const Messages = () => ( 

Messages

Messages
); export default Messages;

And finally, src/component/About.js for the route /about :

import React from 'react'; const About = () => ( 

About

This example shows how to use React Router!
); export default About;

To specify the URL that corresponds to each component, you use the in the following way:

With other router libraries (and even in previous versions of React Router), you have to define these routes in a special file, or at least, outside your application.

This doesn’t apply to React Router 4. These components can be placed anywhere inside of the router, and the associated component will be rendered in that place, just like any other component.

Note: The most recent stable version is React Router v5.2.0, released on 11 May 2020. React Router v.6.0.0 is currently in beta. For more information, check out React Router’s version history.

So in src/App.js , import all these components and add a section after the menu:

// … import < Route, Link >from 'react-router-dom' import Home from './components/Home'; import About from './components/About'; import Messages from './components/Messages'; class App extends Component < render() < return ( 
.
.
/> /> />
); > >

In the browser, you should see something like this:

» width=»720″ height=»297″>

However, look what happens when you go to the other routes:

By default, routes are inclusive; more than one component can match the URL path and render at the same time.

Routes are the most important concept in React Router. Let’s talk about routes in the next section.

Understanding routes

The matching logic of the component is delegated to the path-to-regexp library. I encourage you to check all the options and modifiers of this library and test it live with the express-route-tester.

In the previous example, since the /message and /about paths also contain the character / , they are also matched and rendered.

With this behavior, you can display different components just by declaring that they belong to the same (or a similar) path.

There’s more than one solution.

The first one uses the exact property to render the component only if the defined path matches the URL path exactly:

If you test the application, you’ll see that everything works fine.

The routes /message and /about are still evaluated, but they are not an exact match for / now.

However, if we know that only one route will be chosen, we can use a component to render only the first route that matches the location:

// … import < Route, Link, Switch >from 'react-router-dom' // … class App extends Component < render() < return ( … 
/> /> />
); > >

will make the path matching exclusive rather than inclusive (as if you were using components).

For example, even if you duplicate the route for the Messages component:

When visiting the /messages path, the Messages component will be rendered only once.

However, notice that you’ll still need to specify the exact property for the / path, otherwise, /message and /about will also match / , and the Home component will always be rendered (since this is the first route matched):

But what happens when a nonexistent path is entered? For example http://localhost:3000/non-existent :

React Router DOM: Routes Example (Nonexistent Path)

In a regular JavaScript switch statement, you’ll specify a default clause for this case, right?

In a component, this default behavior can be implemented with a component:

// … import < Route, Link, Switch, Redirect >from 'react-router-dom' // … class App extends Component < render() < return ( … 
/> /> />
); > >

This component will navigate to a new location overriding the current one in the history stack:

Now, let’s cover something a little more advanced, nested routes.

Nested routes

A nested route is something like /about/react .

Let’s say that for the messages section, we want to display a list of messages. Each one in the form of a link like /messages/1 , /messages/2 , and so on, that will lead you to a detail page.

You can start by modifying the Messages component to generate links for five sample messages in this way:

This should be displayed in the browser:

React Router DOM Nested Routes

To understand how to implement this, you need to know that when a component is rendered by the router, three properties are passed as parameters:

For our purposes, we’ll be using the match parameter.

When there’s a match between the router’s path and the URL location, a match object is created with information about the URL and the path. Here are the properties of this object:

  • params : Key/value pairs parsed from the URL corresponding to the parameters
  • isExact : true if the entire URL was matched (no trailing characters)
  • path : The path pattern used to match
  • url : The matched portion of the URL

This way, in the Messages component, we can destructure the properties object to use the match object:

const Messages = (< match >) => ( 
.
)

Replace /messages with the matched URL of the match object:

This way you’re covered if the path ever changes.

And after the message list, declare a component with a parameter to capture the message identifier:

In addition, you can enforce a numerical ID in this way:

/:id(\\d+)`> component= />

If there’s a match, the Message component will be rendered. Here’s its definition:

import React from 'react'; const Message = (< match >) => ( Message with ID ); export default Message;

In this component, the ID of the message is displayed. Notice how the ID is extracted from the match.params object using the same name that it’s defined in the path.

If you open the browser, you should see something similar to the following:

But notice that for the initial page of the messages section ( /messages ) or if you enter in the URL and invalid identifier (like /messages/a ), nothing is printed under the list. A message would be nice, don’t you think?

You can add another route for this case, but instead of creating another component to just display a message, we can use the render property of the component:

 render= 

Please select a message

/>

You can define what is rendered by using one of the following properties of :

  • component to render a component
  • render , a function that returns the element or component to be rendered
  • children , a function that also returns the element or component to be rendered. However, the returned element is rendered regardless of whether the path is matched or not

Finally, we can wrap the routes in a component to guarantee that only one of the two is matched:

However, you have to be careful. If you declare route that renders the message first:

  render= 

Please select a message

> /> /:id(\\d+)`> component= />

The Message component will never be rendered because a path like /messages/1 will match the path /messages .

If you declare the routes in this order, add exact to avoid this behavior:

  render= 

Please select a message

> /> /:id(\\d+)`> component= />

How to set the default route in React

Let’s say we encounter a nonexistent route/path in our app. Instead of letting the browser show an error, we can customize a 404 page to tell our users with a neat UI that the page they are requesting is not available.

It might look something like this:

The /> displays the NotFound component when no other routes match the requested path. It is purposely set at the bottom of the Switch so it will be the last to be matched; putting it at the beginning will cause the NotFound page to always render.

Now, let’s say we don’t like the idea of using a NotFound page to display a nonexistent page. Instead, we want to set a default page to be loaded when a nonexistent route is hit.

Referring back to the above example, we want our Home page to be the default page. This Home page will be displayed when the user navigates to a nonexistent path or route in our app. So instead of a 404 page, a normal page is displayed.

Using an asterisk ( * )

To set up a default page in React Router, pass an asterisk ( * ) to the Route ‘s path prop:

This /> handles nonexistent routes in a special way. The asterisk at the path prop causes the route to be called when a nonexistent path is hit. It then displays the Home component.

Home is now set as the default page. If we navigate to localhost:3000/planets , the Home component will be displayed under the localhost:3000/planets URL. The path does not exist in our routing configuration, so React Router displays our default page, the Home page.

Using Redirect

We can use another technique to set default page in React Router:

This method redirects the URL to / when a nonexistent path is hit in our application and sets the route / and Home as our default page.

So if we navigate to localhost:3000/planets in our browser, React Router will redirect to localhost:3000 and display the Home component because the route localhost:3000/planets does not exist in our routing config.

Using Router with no path props

We did this earlier, but this time we will do away with the Notfound page and set the Route to call our default component.

We want the Home component to be our default component. The /> is run when no route is matched and the Home component is displayed instead.

Conclusion

In a few words, a router keeps your application UI and the URL in sync.

React Router is the most popular router library for React, and since version 4, React Router declarative defines routes with components in the same style as React.

In this post, you have learned how to set up React Router, its most important components, how routes work, and how to build dynamic nested routes with path parameters.

The official documentation covers some basic examples as well as more advanced, interactive use cases.

Get set up with LogRocket’s modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML:   
  • Redux middleware
  • NgRx middleware
  • Vuex plugin

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *