Jan*_*nus 13 javascript routes reactjs react-router react-router-dom
我尝试嵌套一条路线:我在Catalog组件中有一个产品目录,它与 url "backoffice/catalog"匹配。
如果 url 与"backoffice/catalog/edit"匹配,我想路由到Edition组件,但我需要将Edition组件作为Catalog的子级来共享道具。
我真的不明白为什么嵌套路由不起作用,请救救我!如果我的应用程序有任何问题,请毫不犹豫地告诉我,我很了解 JavaScript,但我是从 React 开始的。
这是我的应用程序组件:
import React from "react";
import { Route, Switch } from "react-router-dom";
import { Home } from "./components/Static/Home.js";
import { Dashboard } from "./components/Backoffice/Dashboard.js";
import { Catalog } from "./components/Backoffice/catalog/Catalog.js";
import { Login } from "./components/Login/Login.js";
import { Signup } from "./components/Signup/Signup.js";
import { PrivateRoute } from "./components/PrivateRoute.js";
import "./scss/App.scss";
import {Header} from "./components/Structure/Header";
import {BOHeader} from "./components/Structure/Backoffice/Header";
import {List} from "./components/Listing/List";
function App()
{
return (
<div className="App">
<div className="App-content">
<Switch>
<Route path='/backoffice' component={BOHeader} />
<Route path='/' component={Header} />
</Switch>
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/login' component={Login} />
<Route exact path='/signup' component={Signup} />
<Route path='/listing' component={List}/>
<PrivateRoute exact path='/backoffice' component={Dashboard}/>
<PrivateRoute exact path='/backoffice/catalog' component={Catalog}/>
</Switch>
</div>
</div>
);
}
export default App;Run Code Online (Sandbox Code Playgroud)
这是我的 Catalog 组件(路由是在 render 方法中创建的:
import React from 'react';
import Data from '../../../Utils/Data';
import {Product} from './Product';
import {Edition} from './Edition';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
export class Catalog extends React.Component
{
state = {
title: '',
products: [],
editionProduct: null
};
obtainProducts = () =>
{
Data.products.obtain()
.then(products => {this.setState({products: products});})
};
editProductHandler = product =>
{
this.setState({editionProduct: product});
};
saveProductHandler = product =>
{
Data.products.save(product).then(() => {
this.state.products.map(item => {
item = item._id === product._id ? product : item;
return item;
})
});
};
deleteProductHandler = event =>
{
const productId = event.target.closest('.product-actions').dataset.productid;
let products = this.state.products.filter(product => {
return product._id !== productId;
});
this.setState({products: products}, () => {
Data.products.remove(productId);
});
};
displayProducts = () =>
{
return this.state.products.map(product => {
return (
<li key={product._id} className='catalog-item'>
<Product
deleteProductHandler={this.deleteProductHandler}
editProductHandler={this.editProductHandler}
data={product}
/>
</li>
)
});
};
componentWillMount()
{
this.obtainProducts();
}
render() {
const Products = this.displayProducts();
let { path, url } = useRouteMatch();
return (
<div className={this.state.editionProduct ? 'catalog edit' : 'catalog'}>
<h1>Catalog</h1>
<Switch>
<Route exact path={path}>
<ul className='catalog-list'>{Products}</ul>
</Route>
<Route path={`${path}/edit`}>
<Edition saveProductHandler={this.saveProductHandler} product={this.state.editionProduct} />
</Route>
</Switch>
</div>
);
}
}Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
And*_*nko 19
你不能在Catalog组件内部使用钩子,因为它是一个类组件。因此,您有两种方法可以解决您的问题:
useRouteMatch内部Catalog组件。如果需要获取match组件内部的数据,则需要使用withRouter高阶组件。因此,如果您选择第二种方式,则需要将Catalog组件包装在withRouter:
export default withRouter(Catalog);
Run Code Online (Sandbox Code Playgroud)
将render函数中的一行更改为:
let { path, url } = useRouteMatch();
Run Code Online (Sandbox Code Playgroud)
到:
const { path, url } = this.props.match;
Run Code Online (Sandbox Code Playgroud)
并且不要忘记更改Catalog组件的导入,因为现在您的组件导出为默认值。
由于我在使用 Typescript 设置 React Router 时遇到了同样的问题,我将分 4 个步骤详细介绍 Andrii 的答案:
yarn add react-router-dom --save
yarn add @types/react-router-dom --save-dev
Run Code Online (Sandbox Code Playgroud)
或者
npm install react-router-dom --save
npm install @types/react-router-dom --save-dev
Run Code Online (Sandbox Code Playgroud)
1) 导入高阶组件(本例中为 App)时,请勿使用大括号,因为 App 将默认导出;
2)BrowserRouter 需要在上层而不是将导出为“default withRouter(Class)”的类,以防止出现以下错误:
“您不应在路由器外使用 Route 或 withRouter()”
yarn add react-router-dom --save
yarn add @types/react-router-dom --save-dev
Run Code Online (Sandbox Code Playgroud)
1)从react-router-dom导入,withRouter & RouteComponentProps(或者你自己的 PropType 定义);
2)扩展React.Component,使用RouteComponentProps接口;
3) 将 props 传递给要共享路由数据的组件;
4) withRouter 默认导出高阶类。
npm install react-router-dom --save
npm install @types/react-router-dom --save-dev
Run Code Online (Sandbox Code Playgroud)
通过您的 RouteComponentProps 扩展您的类,您可以正常访问路由道具作为历史、位置和匹配,如下所示:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import * as serviceWorker from './serviceWorker';
import App from './app';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
serviceWorker.unregister();
Run Code Online (Sandbox Code Playgroud)
希望它有所帮助,因为我在使用 webpack 且没有 redux 的简单环境中使用它时遇到了一些挑战。上次使用以下版本正常工作:
{
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"typescript": "^3.8.2",
"webpack": "^4.41.6",
"webpack-dev-server": "^3.10.3",
},
{
"@types/react-router-dom": "^5.1.3",
"webpack-cli": "^3.3.11"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15850 次 |
| 最近记录: |