繁体   English   中英

React-router 组件不会更新<Link>导航

[英]React-router component does not update on <Link> navigation

由于许多其他人遇到了同样的问题,我正在努力与<Link>元素交互以更改路由并呈现新组件。 我可以在我的 redux 存储中单击链接和应用程序更改的路径,但没有更新任何组件。 我的根组件似乎没有响应shouldComponentUpdate ,即使 props 正在更改并且完整设置类似于connected-react-router描述它需要的方式。

去测试

示例代码 (git repo) 是 MVP(最小可行产品) - 它可以轻松复制我所看到的问题。

git clone https://github.com/reZach/electron-webpack-template.git
cd electron-webpack-template
npm i
npm run dev

如果您更喜欢查看文件,我在下面包含了必要的文件

索引.js

import React from "react";
import ReactDOM from "react-dom";
import Root from "../app/components/core/root";
import store, { history } from "./redux/store/store";

ReactDOM.render(
    <Root store={store} history={history}></Root>,
    document.getElementById("root")
);

商店.js

import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
import { createBrowserHistory } from "history";
import { routerMiddleware } from "connected-react-router";
import rootReducer from "../reducers/rootReducer";

export const history = createBrowserHistory();

const store = configureStore({
    reducer: rootReducer(history),
    middleware: [...getDefaultMiddleware(), routerMiddleware(history)]
});

export default store;

根.jsx

import React from "react";
import { ConnectedRouter } from "connected-react-router";
import { Provider, connect } from "react-redux";
import Routes from "../core/routes";

class Root extends React.Component {
    render() {
        return (
            <Provider store={this.props.store}>
                <ConnectedRouter history={this.props.history}>
                    <Routes></Routes>
                </ConnectedRouter>
            </Provider>
        );
    }
}

export default Root;

路由.jsx

import React from "react";
import { Switch, Route } from "react-router";
import routes from "../../constants/routes";
import App from "../app/app";
import Page2 from "../page2/page2";

class Routes extends React.Component {    
    render() {
        return (
            <Switch>
                <Route path={routes.ENTRY} component={App}></Route>
                <Route path={routes.MAIN} component={Page2}></Route>
            </Switch>
        );
    }
}

export default Routes;

路由文件

{
    "ENTRY": "/",
    "MAIN": "/main"
}

包.json

{
  "name": "electron-webpack-template",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "npm run build-dev-webpack && npm run start-dev-app",
    "build-dev-webpack": "webpack --mode development --config ./app/configs/webpack/webpack.config.js",
    "start-dev-app": "cross-env NODE_ENV=development electron app/main.js",
    "prod": "npm run build-prod-webpack && npm run start-prod-app",
    "build-prod-webpack": "webpack --mode production --config ./app/configs/webpack/webpack.config.js",
    "start-prod-app": "cross-env NODE_ENV=production electron app/main.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/reZach/electron-webpack-template.git"
  },
  "keywords": [],
  "author": "",
  "license": "GPL-3.0-only",
  "bugs": {
    "url": "https://github.com/reZach/electron-webpack-template/issues"
  },
  "homepage": "https://github.com/reZach/electron-webpack-template#readme",
  "devDependencies": {
    "@babel/core": "^7.7.7",
    "@babel/plugin-proposal-json-strings": "^7.7.4",
    "@babel/plugin-transform-react-jsx": "^7.7.7",
    "@babel/preset-env": "^7.7.7",
    "babel-loader": "^8.0.6",
    "cross-env": "^6.0.3",
    "csp-html-webpack-plugin": "^3.0.4",
    "devtron": "^1.4.0",
    "electron": "^7.1.7",
    "html-webpack-plugin": "^3.2.0",
    "lockfile-lint": "^3.0.5",
    "webpack": "^4.41.4",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1"
  },
  "dependencies": {
    "@reduxjs/toolkit": "^1.2.1",
    "connected-react-router": "^6.6.1",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-redux": "^7.1.3",
    "react-router": "^5.1.2",
    "react-router-dom": "^5.1.2",
    "redux": "^4.0.5"
  }
}

这可能是因为 Entry 路由上没有“确切”字样(对于 App 组件):

<Switch>
   <Route exact path={routes.ENTRY} component={App}></Route>
   <Route path={routes.MAIN} component={Page2}></Route>
</Switch>

这些路由问题的解决方案是添加drazewski建议的exact属性,另外更改我用于<ConnectedRouter>的历史对象。 问题是由我使用createBrowserHistory以及我没有在我的应用程序中使用网络服务器来托管我的文件的事实引起的。 加载我的应用程序时我的应用程序的默认路径是file:///C:/...index.html 这是应用加载时我在 Redux 商店中查看时的路径值。

我不得不改为使用createHashHistory ,这在您没有托管网络服务器来托管您的应用程序时有效。 默认路径使用createHashHistory时是/ ,它匹配routes.ENTRY我routes.jsx文件,并让我可以导航到/main 显然,除非您的路径与您在<Route>定义的现有路径匹配,否则您无法导航到另一条路径(这就是我在上面描述我的问题时所认为的情况 - 尽管我不知道为什么我的家/page1 组件完全呈现......)。

这里有很好的参考资料,它们为我指明了我必须改变历史的方向(这里这里)。 除了这些链接之外,这里还有一篇很好的博客文章镜像),更详细地解释了react-router 的各种类型的历史记录。

新路线.jsx

import React from "react";
import { Switch, Route } from "react-router";
import routes from "../../constants/routes";
import App from "../app/app";
import Page2 from "../page2/page2";

class Routes extends React.Component {    
    render() {
        return (
            <Switch>
                <Route exact path={routes.ENTRY} component={App}></Route> <!-- updated -->
                <Route path={routes.MAIN} component={Page2}></Route>
            </Switch>
        );
    }
}

export default Routes;

新商店.js

import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
import { createHashHistory } from "history"; // < updated!
import { routerMiddleware } from "connected-react-router";
import rootReducer from "../reducers/rootReducer";

export const history = createHashHistory(); // < updated!

const store = configureStore({
    reducer: rootReducer(history),
    middleware: [...getDefaultMiddleware(), routerMiddleware(history)]
});

export default store;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM