Не удается получить историю.нажмите(url), чтобы повторно отобразить страницу

#javascript #reactjs #react-router-dom

Вопрос:

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

В моем последнем проекте create-react-app у меня не было проблем с отображением новых страниц с маршрутизатором и историей использования. Используя точно такую же настройку, я столкнулся с проблемой, когда history.push(url) изменяется URL-адрес в адресной строке, но страница не отображается повторно.

Я использую:

  • Реагировать v17.0.2
  • реагировать-маршрутизатор-dom v5.3.0
  • история v5.0.1 (также предпринята попытка на v4.10.1)

App.js

 import React from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Page } from './stories/Page';
import './App.css';

function App() {


    return (
            <Router>
                <Switch>
                    <Route exact path="/">
                        <Page homepage={true} />
                    </Route>
                    <Route path="/project/([a-zA-Z0-9] )/([a-z-0-9] )/([a-z-0-9] )/" render={urlprops =>
                        <Page projectID={urlprops.match.params[0]} homepage={false} />
                    } />
                    <Route path="/project/([a-zA-Z0-9] )/([a-z-0-9] )/" render={urlprops =>
                        <Page projectID={urlprops.match.params[0]} homepage={false} />
                    } />
                </Switch>
            </Router>
        
    );

}

export default App;
 

component-page.js

 import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom'; 
import './menuitem.css';

export const Component = ({ url, ...props }) => {

    let history = useHistory();

    function handleItemClick(e) {
        history.push(url); // <- calls fine, tested with logging to console
    }
    ...
 

Я видел, как старые решения предлагали передавать реквизиты истории через маршрутизатор, но в моем последнем приложении я смог использовать настройку выше, и любой вложенный подкомпонент уровня мог бы вызвать крючок истории использования и использовать push, если бы они были настроены так component-page.js выше. Поэтому я не показал компоненты между App.js и component-page.js исходя из убеждения, что это не должно иметь отношения к useHistory правильному функционированию.

Possibly relevant:

  • If I enter the URLS in the address bar and hit return, Router renders the correct components, suggesting Router and Switch work fine with a freshly loaded page.
  • I have React dev tools set up to blink on
    components when they re-render. After history.push(url) is called all
    components blink, though none re-render (visually, at least).
  • Downgrading history to 4.10.1 seemed to fix a lot
    of the recent reports of this issue for others. I had no such luck. Apparently there was/is a bug with react-router-dom v5 which meant history.push was not working with history v5 .
  • Я также поместил простой компонент кнопки в компонент страницы, который отправил запрос на history.push(«url-адрес строки здесь») с той же проблемой. Он звонит, адресная строка меняется, страница не отображается повторно. На мой взгляд, это исключает, что это какая-то проблема с гнездованием, в которую я все равно не верил.

Обновить

Проверка истории в консоли после вызова history.push('url string') показывает следующее в свойстве location. Похоже, что он действует так, как задумано (я ожидаю, что имя пути будет соответствовать URL-адресу, на который я пытался указать).

 {
    "pathname": "url string",
    "search": "",
    "hash": "",
    "key": "ctks7v"
}
 

Обновление 2

Возможный прогресс. В моем компоненте страницы я вызываю fetch в крючке, чтобы поймать любое обновление, например так:

 useEffect(() => {
    apiFetchProject(projectID);
}, []);
 

Теперь я задаюсь вопросом, не моя ли это проблема? Что этот крючок не рассматривает URL-адрес как изменение, требующее запуска apiFetchProject(projectID) . Причина, по которой я говорю это, заключается в том, что вызовы консоли подтверждают, что этот крючок не вызывается здесь после моей истории.push, но происходит консольный вызов компонента Страницы. Я пытался вызвать крючок с любым изменением, props.location но каждый раз это возвращается как неопределенное, что означает, что крючок не вызывается.

Обновление 3

Если на странице я использую import { useLocation } from "react-router-dom"; с let location = useLocation(); и позволяю крючку искать изменения location , страница теперь успешно звонит fetch после history.push звонка. Но что-то кажется неправильным в том, чтобы делать и это тоже? Я чувствую, что воспринял бы это как стандартную инструкцию.

Мне нужно добавить его в каждый компонент, чтобы увидеть повторную визуализацию чего-либо. Страница «Выборка» хранится как состояние и передается в качестве поддержки подкомпонентам. Изменение этого состояния должно автоматически повторно отображать все переданные ему подкомпоненты, как это происходит при загрузке страницы.

Комментарии:

1. Некоторое время назад у меня была аналогичная проблема, и я думаю, что решил ее, «обманув» react в повторном рендеринге, предоставив ему новый ключ с использованием метки времени.

Ответ №1:

вместо URL-адреса укажите путь (‘/home’)

Комментарии:

1. Я не уверен, что понимаю это предложение? URL — адрес должен быть динамической переменной и в любом случае должен соответствовать одному из путей переключения. С точки зрения отладки, я попытался использовать строки вместо переменной url, чтобы исключить эту проблему (ее не было).

2. Извините, но это вообще не отвечает на вопрос — вопрос по сути сводится к «У меня проблема с отображением новых страниц с маршрутизатором и историей использования при вызове history.push(url). URL-адрес в адресной строке изменяется, но страница не отображается повторно».