Изменение URL без повторного рендеринга в маршрутизаторе React

Я работаю над приложением, в котором мне нужно изменить URL-адрес страницы, не вызывая повторного рендеринга.

Я делаю вызов, чтобы получить все страницы внутри componentDidMount, как это

componentDidMount() {    
    axios.get('/pages')
      .then(response => {
        this.setState({
          pages: response.data,
          slugs: response.data.pages.map(item => Slug(item.title))
        })
      })

Когда у меня есть все страницы, я хочу показать отдельные страницы. Например. в URL-адресе он должен быть похож на /page/1/slug-for-page-1 и /page/2/slug-for-page-2 на основе переменной состояния activePageNumber, и будет отображаться активное содержимое страницы. Также соответствующий слаг должен быть в URL-адресе.

Я попытался добавить обратный вызов после setState, как показано ниже, но это не сработало.

() => this.props.history.push({
          pathName: '/page',
          state: {activePageNumber : activePageNumber},
        })

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

Я могу реализовать его таким образом, чтобы каждая страница делала отдельный запрос к серверной части, но я хочу вызвать его только один раз, а затем обновить URL-адрес на основе номера активной страницы.

Я не уверен, как реализовать это в реакции.

У меня есть следующие версии

"react-router-dom": "^5.0.0"

"react": "^16.8.6"

По какому URL-адресу вы загружаете страницы, прежде чем переключиться на «/page/1»?

steenuil 09.05.2019 09:40

Это «/страницы».

Shahrukh Mohammad 09.05.2019 10:14

Итак, сначала вы переходите к маршруту «/pages», а затем переходите к «/page/1» после получения страниц? Вы действительно должны просто перейти к "/page/1" и получить данные оттуда.

steenuil 09.05.2019 11:44

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

Shahrukh Mohammad 09.05.2019 11:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
10
4
10 034
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы определяете свой маршрут /page следующим образом:

<Route
  path = "/page/:number"
  component = {({ match }) => (
    <Pages activePageNumber = {match.params.number} />
  )}
/>

Метод компонента Pages будет вызываться при переключении, например, с componentDidMount на /home, но будет вызываться нет при переключении с /page/1 на /page/1, потому что элементы DOM внутри /page/2 Route остаются того же типа. Я предлагаю вам прочитать документацию React по примирение для лучшего объяснения.

Таким образом, вы можете смело поместить вызов вашего /page/:number сервиса внутри /pages компонента, а затем в его методе рендеринга отобразить нужную вам страницу на основе Pages prop.

class Pages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      pages: null,
    };
  }

  componentDidMount() {
    axios.get('/pages')
      .then(response => {
        this.setState({
          pages: response.data
        })
      });
  }

  render() {
    const { pages } = this.state;
    const { activePageNumber } = this.props;

    return pages ? (
      <Page page = {pages[activePageNumber]} />
    ) : (
      <div>loading...</div>
    );
  }
}

Спасибо за ответ, но есть еще одна проблема, у меня есть слаг для каждой страницы, который я вычисляю из заголовка каждой страницы, полученного из ответа axios, поэтому URL-адрес каждой страницы выглядит как /page/1/new-game, а также домашняя страница, откуда Я ссылаюсь, не знает об этом слизняке. Как мне справиться с этим?

Shahrukh Mohammad 09.05.2019 17:21

@ShahrukhMohammad, вы можете изменить реквизит пути в маршруте с помощью /page/:number/:title?, чтобы он соответствовал как /page/1, так и /page/1/new-game, см. этот ответ. На главной странице вы можете сделать ссылку на /page/1, и когда вы получите ответ от сервера в обратном вызове setState, вы можете заменить этот URL на /page/1/title-of-the-page.

steenuil 09.05.2019 17:58

Другие вопросы по теме