【问题标题】:Cannot get history.push(url) to re-render page无法让 history.push(url) 重新渲染页面
【发布时间】:2021-11-10 01:18:37
【问题描述】:

这经常出现,但似乎没有解决方案有效,我觉得我已经用尽了我能想到的每一个选项,所以我转向这里,相信这可能是一个稍微不同的场景,而不是重复。如果有可行的现有解决方案,我很高兴得到其他展示。

在我上一个 create-react-app 项目中,使用 RouteruseHistory 渲染新页面没有问题。使用完全相同的设置,我遇到了history.push(url) 更改地址栏中的 url 但页面没有重新呈现的问题。

我正在使用:

  • 反应 v17.0.2
  • react-router-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
    }
    ...

我看到旧的解决方案建议通过 Router 传递历史道具,但在我的上一个应用程序中,我能够使用上面的设置,并且任何级别嵌套的子组件都可以调用 useHistory 如果像上面的 component-page.js 那样设置,则挂钩并使用 push。因此,我没有展示 App.jscomponent-page.js 之间的组件,因为我认为这应该与 useHistory 正常运行无关。

可能相关:

  • 如果我在地址栏中输入 URL 并回车,Router 会呈现正确的组件,提示 RouterSwitch 可以正常工作一个新加载的页面。
  • 我已将 React 开发工具设置为闪烁 组件重新渲染时。在history.push(url) 被全部调用之后 组件闪烁,但没有重新渲染(至少在视觉上)。
  • 将历史记录降级到 4.10.1 似乎解决了很多问题 其他人对此问题的最新报告。我没有这样的运气。显然,react-router-dom v5+ 存在/存在一个错误,这意味着 history.push 不适用于 history v5+。
  • 我还在 Page 组件中放置了一个简单的按钮组件,该组件向 history.push("string url here") 发出了相同问题的请求。它调用,地址栏更改,页面不会重新呈现。在我看来,这排除了它是某种嵌套问题,无论如何我都不相信它。

更新

在调用history.push('url string') 后在控制台中检查历史记录会在 location 属性下显示以下内容。这看起来像预期的那样(我只希望路径名与我试图指向的 url 匹配)。

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

更新 2

可能的进展。在我的 Page 组件中,我在挂钩中调用 fetch 以捕获任何更新,如下所示:

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

我现在想知道这是否是我的问题?这个钩子没有将 url 视为需要触发 apiFetchProject(projectID) 的更改。我这么说的原因是控制台调用确认在我的 history.push 之后没有在此处调用此钩子,但是对 Page 组件的控制台调用 正在发生。我已经尝试在 props.location 中进行任何更改来调用该钩子,但这每次都会返回为未定义,这意味着不会调用该钩子。

更新 3

如果在 Page 上,我使用 import { useLocation } from "react-router-dom";let location = useLocation(); 并让钩子查找 location 的变化,Page 现在可以成功调用 @987654334 @ 在history.push 呼叫之后。但是也必须这样做似乎有些不对劲?我觉得我会将其视为标准说明。

我必须将它添加到每个组件中才能看到重新渲染的任何内容。 Page 中的 fetch 存储为状态,并作为 prop 传递给子组件。此状态的更改应自动重新呈现所有传递给它的子组件,就像加载页面时发生的那样。

【问题讨论】:

  • 前段时间我也遇到过类似的问题,我想我是通过“欺骗”响应重新渲染来解决的,方法是使用时间戳给它一个新的键。

标签: javascript reactjs react-router-dom


【解决方案1】:

而不是url,放路径('/home')

【讨论】:

  • 我不确定我是否理解该建议? url 需要是一个动态变量,并且无论如何都需要匹配 Switch 路径之一。在调试方面,我尝试使用字符串而不是 url 变量来排除问题(不是)。
  • 对不起,但这根本不能回答问题 - 问题本质上归结为 “我在调用 history.push(url) 时使用 Router 和 useHistory 渲染新页面时遇到问题。地址栏中的 url 发生变化,但页面不会重新呈现。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2018-11-28
  • 2021-10-03
  • 2021-12-18
  • 2017-03-20
相关资源
最近更新 更多