React router Link 不会导致组件在嵌套路由内更新

2024-04-04

这真让我抓狂。当我尝试在嵌套路由中使用 React Router 的 Link 时,链接会在浏览器中更新,但视图不会改变。然而,如果我刷新页面到链接,它就会出现。不知何故,该组件没有在应该更新的时候更新(或者至少这是目标)。

这是我的链接的样子(上一个/下一个项目实际上是变量):

<Link to={'/portfolio/previous-item'}>
    <button className="button button-xs">Previous</button>
</Link>
<Link to={'/portfolio/next-item'}>
    <button className="button button-xs">Next</button>
</Link>

一个hacky解决方案是手动调用forceUpdate(),例如:

<Link onClick={this.forceUpdate} to={'/portfolio/next-item'}>
    <button className="button button-xs">Next</button>
</Link>

这有效,但会导致整个页面刷新,这是我不想要的并且出现错误:

ReactComponent.js:85 Uncaught TypeError: Cannot read property 'enqueueForceUpdate' of undefined

我到处寻找答案,我能找到的最接近的答案是:https://github.com/reactjs/react-router/issues/880 https://github.com/reactjs/react-router/issues/880。但它很旧,而且我没有使用纯渲染混合。

以下是我的相关路线:

<Route component={App}>
    <Route path='/' component={Home}>
        <Route path="/index:hashRoute" component={Home} />
    </Route>
    <Route path="/portfolio" component={PortfolioDetail} >
        <Route path="/portfolio/:slug" component={PortfolioItemDetail} />
    </Route>
    <Route path="*" component={NoMatch} />
</Route>

无论出于何种原因,调用 Link 都不会导致组件重新安装,而需要重新安装组件才能获取新视图的内容。它确实调用了 componentDidUpdate,我确信我可以检查 url slug 更改,然后在那里触发我的 ajax 调用/视图更新,但似乎不需要这样做。

编辑(更多相关代码):

PortfolioDetail.js

import React, {Component} from 'react';
import { browserHistory } from 'react-router'
import {connect} from 'react-redux';
import Loader from '../components/common/loader';
import PortfolioItemDetail from '../components/portfolio-detail/portfolioItemDetail';
import * as portfolioActions  from '../actions/portfolio';

export default class PortfolioDetail extends Component {

    static readyOnActions(dispatch, params) {
        // this action fires when rendering on the server then again with each componentDidMount. 
        // but not firing with Link...
        return Promise.all([
            dispatch(portfolioActions.fetchPortfolioDetailIfNeeded(params.slug))
        ]);
    }

    componentDidMount() {
        // react-router Link is not causing this event to fire
        const {dispatch, params} = this.props;
        PortfolioDetail.readyOnActions(dispatch, params);
    }

    componentWillUnmount() {
        // react-router Link is not causing this event to fire
        this.props.dispatch(portfolioActions.resetPortfolioDetail());
    }

    renderPortfolioItemDetail(browserHistory) {
        const {DetailReadyState, item} = this.props.portfolio;
        if (DetailReadyState === 'WORK_DETAIL_FETCHING') {
            return <Loader />;
        } else if (DetailReadyState === 'WORK_DETAIL_FETCHED') {
            return <PortfolioItemDetail />; // used to have this as this.props.children when the route was nested
        } else if (DetailReadyState === 'WORK_DETAIL_FETCH_FAILED') {
            browserHistory.push('/not-found');
        }
    }

    render() {
        return (
            <div id="interior-page">
                {this.renderPortfolioItemDetail(browserHistory)}
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        portfolio: state.portfolio
    };
}
function mapDispatchToProps(dispatch) {
    return {
        dispatch: dispatch
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(PortfolioDetail);

PortfolioItemDetail.js

import React, {Component} from 'react';
import {connect} from 'react-redux';
import Gallery from './gallery';

export default class PortfolioItemDetail extends React.Component {

    makeGallery(gallery) {
        if (gallery) {
            return gallery
                .split('|')
                .map((image, i) => {
                    return <li key={i}><img src={'/images/portfolio/' + image} alt="" /></li>
            })
        }
    }

    render() {
        const { item } = this.props.portfolio;

        return (
            <div className="portfolio-detail container-fluid">
                <Gallery
                    makeGallery={this.makeGallery.bind(this)}
                    item={item}
                />
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        portfolio: state.portfolio
    };
}

export default connect(mapStateToProps)(PortfolioItemDetail);

画廊.js

import React, { Component } from 'react';
import { Link } from 'react-router';

const Gallery = (props) => {

    const {gallery, prev, next} = props.item;
    const prevButton = prev ? <Link to={'/portfolio/' + prev}><button className="button button-xs">Previous</button></Link> : '';
    const nextButton = next ? <Link to={'/portfolio/' + next}><button className="button button-xs">Next</button></Link> : '';

    return (
        <div>
            <ul className="gallery">
                {props.makeGallery(gallery)}
            </ul>
            <div className="next-prev-btns">
                {prevButton}
                {nextButton}
            </div>
        </div>
    );
};

export default Gallery;

新路线,基于Anoop的建议:

<Route component={App}>
    <Route path='/' component={Home}>
        <Route path="/index:hashRoute" component={Home} />
    </Route>
    <Route path="/portfolio/:slug" component={PortfolioDetail} />
    <Route path="*" component={NoMatch} />
</Route>

无法追根究底,但我能够使用 ComponentWillRecieveProps 实现我的目标:

componentWillReceiveProps(nextProps){
    if (nextProps.params.slug !== this.props.params.slug) {
        const {dispatch, params} = nextProps;
        PortfolioDetail.readyOnActions(dispatch, params, true);
    }
}

换句话说,无论出于何种原因,当我使用 React Router Link 链接到具有相同父组件的页面时,它都不会触发 componentWillUnMount/componentWillMount。所以我必须手动触发我的操作。每当我链接到具有不同父组件的路由时,它都会按照我的预期工作。

也许这是设计好的,但看起来不正确而且不直观。我注意到 Stackoverflow 上有很多关于 Link 更改 url 但不更新页面的类似问题,所以我不是唯一的一个。如果有人对此有任何见解,我仍然很想听听!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React router Link 不会导致组件在嵌套路由内更新 的相关文章

随机推荐

  • qwt 图表示例 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 大家好 我正在使用 qwt 我是新手 我想使用 qwt 和 qt 创建者绘制图表 我不知道要在我的 qt 项目中包含哪些库来绘制图表 我已
  • 在 Python 中下载、解压并读取 gzip 文件

    我想在 Python 中下载 提取和迭代文本文件 而无需创建临时文件 基本上 这个管道 但是在 python 中 curl ftp ftp theseed org genomes SEED SEED fasta gz gunzip proc
  • Array.prototype.filter.call(forms, function(form) 这是做什么的?

    我很难完全理解这段代码是如何工作的 这只是表单验证代码复制并从引导程序粘贴 我的问题从这一行开始 var 验证 Array prototype filter call forms function form 在我看来 它正在创建一个名为va
  • 如果启用身份验证,Azure 上的查询/标头太大

    我有一个在本地运行良好的节点 快速应用程序 我已将其上传到 Azure Web App 只要我不启用身份验证 它就可以正常工作 当我启用 AAD 身份验证时 应用程序失败并显示状态 500 1011 错误请求 我的网址中有很多查询参数 如果
  • 在 Git 中:为什么经常提交是件好事? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 所以我对 Git 和 DVCS 总体来说还很陌生 而且我一直在到处读到 至少在私有分支上 一直提交总是好的 问题是 为什么 我正在使用 Sour
  • 纯Python四叉树实现

    All 有一些使用 Python 实现四叉树的示例 但我的问题是 有谁知道用纯 python 编写的类 在单个 py 文件中 我可以轻松地将其包含在我的项目中 这里列出了三个最受欢迎的软件包这些四叉树库中的任何一个都好吗 https sta
  • Silverlight:如何处理标准程序集

    一个常见的 Silverlight 任务 减小 xap 文件的大小 有很多热门手册解释了如何使应用程序模块化 但我没有找到任何人解释如何制作 模块化 标准库 我的 xap 文件的最大部分 1 7Mb 当整体大小为 1 8Mb 时 被标准程序
  • 访问 Scala 中可用但 PySpark 中不可用的依赖项

    我正在尝试访问 RDD 的依赖项 在 Scala 中 这是一个非常简单的代码 scala gt val myRdd sc parallelize 0 to 9 groupBy 2 myRdd org apache spark rdd RDD
  • Java 执行器无法对任务进行排队

    我需要一个 Java 执行器 如果正在处理其他任务 它会拒绝任务 我想不可能操纵工作队列大小 有人可能会奇怪 为什么我首先需要一个具有这种特征的执行者 我需要能够轻松更改策略并允许非零队列大小 有任何想法吗 Use a 线程池执行器 htt
  • 对 href 使用 JavaScript 单引号和双引号

    我在转义单引号和双引号时遇到问题hrefJavaScript 函数 我里面有这段 JavaScript 代码href 就像是 a href a fileName doc true gt click this 现在 由于双引号内的双引号无效
  • 如何在 Sails.js 策略中使用错误处理程序回调?

    问完后这个问题 https stackoverflow com questions 22160043 how to use a callback array as the handler for a sails js route 我发现我可
  • lubuntu 的洞察调试器有其他选择吗?

    你能告诉我是否有其他选择洞察力 调试器或者如何使用调试器运行和调试 Jeff Duntemann 的 汇编语言分步第三版 中的汇编代码 其中输出 与书中示例中描述的输出相同吗 我在汇编计划学习方面完全是菜鸟 所以有人向我推荐了这本书 但是我
  • 使用 Vee-Validate 和 vue js 2 在提交时验证子输入组件

    我目前正在尝试创建一个包含多个 输入字段 组件的注册表单 这些组件都需要在按下 提交 后进行验证 目前 当其中的文本发生更改时 它们都会自行验证 但我发现很难对所有输入字段进行全局调用以验证所有输入字段 我想要实现的目标如下 http ve
  • .Net Mvc 3 触发器(提交按钮除外)非侵入式验证

    我想要什么 我想通过我选择的事件在我的视图中触发客户端验证 它可能是 onblur 也可能是另一个按钮 但不是提交按钮 相关链接 如何在不使用提交按钮的情况下触发验证 https stackoverflow com questions 57
  • 删除字符串中不需要的字符

    我想问如何从字符串中删除特殊字符 从废弃页面中提取 4 30am 我只是想获得时间 所以我尝试使用以下方法过滤它 str 4 30am new string preg replace A Za z0 9 str echo pre new s
  • 使用 pandas 读取带有 numpy 数组的 csv

    我有一个csv包含 3 列的文件emotion pixels Usage包含由 组成35000行例如0 70 23 45 178 455 Training I used pandas read csv阅读csv文件为pd read csv
  • XPath 元素包含 2 个子元素,每个子元素都与特定文本匹配

    我正在使用 Selenium 来定位页面上的某些元素 我有一张看起来像这样的桌子 table tbody tr td Text1 td td Text2 td tr tbody table Each 元素与此模式匹配 我想传入两个字符串 t
  • 尝试映射具有重复值的系列时出现 InvalidIndexError

    我正在尝试将医院名称映射到其英国邮政编码 我有这些医院 在英国称为 Trusts 的脊柱手术的 csv 该 csv 是 kate spine csv 我从中导入一列 信任 以简化操作 import pandas as pd spine pd
  • Pod 和部署有什么区别?

    我一直在创建豆荚type deployment但我看到一些文档使用type pod 进一步来说多容器 Pod 的文档 http kubernetes io docs user guide pods multi container apiVe
  • React router Link 不会导致组件在嵌套路由内更新

    这真让我抓狂 当我尝试在嵌套路由中使用 React Router 的 Link 时 链接会在浏览器中更新 但视图不会改变 然而 如果我刷新页面到链接 它就会出现 不知何故 该组件没有在应该更新的时候更新 或者至少这是目标 这是我的链接的样子