使用更深层的路径来对路由器进行反应

时间:2020-02-02 07:06:34

标签: reactjs typescript routes react-router tsx

我正在尝试运行React Router的例子。

我的示例具有以下3条路线:

  1. (在浏览器中可用)http://0.0.0.0:8081/one
  2. (在浏览器中失败)http://0.0.0.0:8081/one/two
  3. (在浏览器中失败)http://0.0.0.0:8081/one/two/three

所有路由都可与Link一起使用,但是在浏览器中键入URL时只有1.可用。在浏览器中输入即2.路由时,浏览器控制台会响应以下错误:

获取http://0.0.0.0:8081/one/app.js净值:: ERR_ABORTED 404(未找到)

主要应用类别:

import * as React from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';

export class App2 extends React.Component<{}, {}> {
    public render() {
        return <BrowserRouter>
            <ul>
                <li>
                    <Link to='/one'>One</Link>
                </li>
                <li>
                    <Link to='/one/two'>Two</Link>
                </li>
                <li>
                    <Link to='/one/two/three'>Three</Link>
                </li>
            </ul>
            <Switch>
                <Route path='/one/two/three' component={Three} />
                <Route path='/one/two' component={Two} />
                <Route path='/one' component={One} />
            </Switch>
        </BrowserRouter>;
    }
}

名为“ One”的类:

import * as React from 'react';

export class One extends React.Component<{}, {}> {
    public render() {
        return <div>One</div>;
    }
}

名为2的类:

import * as React from 'react';

export class Two extends React.Component<{}, {}> {
    public render() {
        return <div>Two</div>;
    }
}

名为“三”的类:

import * as React from 'react';

export class Three extends React.Component<{}, {}> {
    public render() {
        return <div>Three</div>;
    }
}

在开发模式下运行应用程序的命令:

"scripts": {
    "develop": "webpack-dev-server --mode development --open --port 8081 --host 0.0.0.0 --config webpack.dev.config.js"
}

Webpack配置webpack.dev.config.js:

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const htmlPlugin = new HtmlWebPackPlugin({
    template: "./src/index.html",
    filename: "./index.html"
});

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "app.js",
        path: path.resolve(__dirname, "dist")
    },

    // Enable sourcemaps for debuggin webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts', and '.tsx' as resolvable exteensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" },

            {
                test: /\.css$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "typings-for-css-module-loader", options: { modules: true, namedExport: true, camelCase: true, localIdentName: "[name]_[local]_[hash:base64]" }}
                ]
            },

            {
                test: /\.scss$/,
                exclude: /\.global.scss$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "typings-for-css-modules-loader", options: { modules: true, namedExport: true, camelCase: true, localIdentName: "[local]" }},
                    { loader: "postcss-loader", options: { plugins: function () { return [ require("autoprefixer") ]; }}},
                    { loader: "sass-loader" }
                ]
            },

            {
                test: /\.scss$/,
                include: /\.global.scss$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "css-loader" },
                    { loader: "postcss-loader", options: { plugins: function () { return [ require("autoprefixer") ]; }}},
                    { loader: "sass-loader" }
                ]
            }
        ]
    },

    devServer: {
        historyApiFallback: true,
        disableHostCheck: true
    },

    plugins: [
        new CleanWebpackPlugin({
            cleanAfterEveryBuildPatterns: ['dist']
        }),
        htmlPlugin
    ]
};

我使用以下版本:

  • 节点v13.7.0
  • “ @类型/反应”:“ 16.9.11”,
  • “ @ types / react-dom”:“ 16.9.4”,
  • “ @ types / react-router-dom”:“ 5.1.2”,
  • “反应”:“ 16.11.0”,
  • “ react-dom”:“ 16.11.0”,
  • “ react-router-dom”:“ 5.1.2”,
  • “打字稿”:“ 3.7.4”,
  • “ webpack”:“ 4.41.2”,
  • “ webpack-cli”:“ 3.3.10”,
  • “ webpack-dev-server”:“ 3.9.0”

我尝试遵循示例here

为什么只有1.路由有效?为什么其他路线2.和3.不起作用?

编辑1:

尝试使用精确也不行。结果与上面提到的相同:

import * as React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';

export class App2 extends React.Component<{}, {}> {
    public render() {
        return <BrowserRouter>
            <Switch>
                <Route exact path='/one' component={One} />
                <Route exact path='/one/two' component={Two} />
                <Route exact path='/one/two/three' component={Three} />
            </Switch>
        </BrowserRouter>;
    }
}

编辑2:

尝试更改顺序也不起作用。结果与上面提到的相同:

import * as React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';

export class App2 extends React.Component<{}, {}> {
    public render() {
        return <BrowserRouter>
            <Switch>
                <Route path='/one/two/three' component={Three} />
                <Route path='/one/two' component={Two} />
                <Route path='/one' component={One} />
            </Switch>
        </BrowserRouter>;
    }
}

2 个答案:

答案 0 :(得分:2)

简单来说:最具体的路线在前。只需取消您的订单即可。

与大多数路由器一样,每个路由器都按顺序检查是否匹配。

编辑1:证据https://reacttraining.com/react-router/web/guides/primary-components

编辑2:。您的404错误向我表明问题不是路由器,而是服务器。在开发过程中,您是否构建了服务器或者webpack-dev-server是预制的服务器?我想您会发现,如果转到/ one并单击到/ one / two,它将真正起作用。

编辑3:您的webpack开发服务器配置需要一些东西。我对此没有经验,但是这是我认为应该有所帮助的doc webpack.js.org/configuration/output/#outputpublicpath。

如注释中所建议:最终的解决方案是在Webpack配置中将publicPath: '/'添加到output

答案 1 :(得分:1)

尝试在您的<Route/>

中使用 exact

由于您的路径始终以/one开头,因此react router仅匹配该部分,如果您想更深入,则必须告诉他 exact (ly)您想要的内容。

<Route exact path='/one' component={One} />
<Route exact path='/one/two' component={Two} />
<Route exact path='/one/two/three' component={Three} />

以下是指向docs

的链接