反应路由器混乱
Posted
技术标签:
【中文标题】反应路由器混乱【英文标题】:React Router confusion 【发布时间】:2017-07-25 12:17:47 【问题描述】:新反应和反应路由器。
我试图理解这个例子:
https://github.com/ReactTraining/react-router/blob/1.0.x/docs/API.md#components-1
但是 this.props 从不包含主栏或侧边栏。我的代码:
Main.js
ReactDOM.render(
<Router>
<Route path="/" component=App2>
<Route path="/" components=main: Home, sidebar: HomeSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
App2.js
class App2 extends React.Component
render()
const main, sidebar = this.props;
return (
<div>
<Menu inverted vertical fixed="left">
sidebar
</Menu>
<Container className="main-container">
main
</Container>
</div>
);
export default App2;
Home.js
import React from 'react';
class Home extends React.Component
render()
return (
<div><h1>Home</h1></div>
);
export default Home;
HomeSidebar.js
class HomeSidebar extends React.Component
render()
return (
<div>
<p>I'm a sidebar</p>
</div>
);
export default HomeSidebar;
我将电子与反应开发工具一起使用。每当我调试时,this.props 既不包含主边栏也不包含边栏。知道为什么会这样吗?
我也尝试过使用 IndexRoute,但它似乎不支持 components 属性。
我尝试过的其他方法
ReactDOM.render(
<Router>
<Route component=App2>
<Route path="/" components=main: Home, sidebar: HomeSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
ReactDOM.render(
<Router>
<Route path="/" component=App2 components=main: Home, sidebar: HomeSidebar>
<Route path="admin" components=main: Admin, sidebar: AdminSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
【问题讨论】:
我删除了关于具有相同路径的路线的答案,因为它对您没有帮助。但这就是我前段时间解决类似问题的方法。 【参考方案1】:看起来你需要使用<IndexRoute />
组件而不是<Route />
来让组件支持工作。在 react-router 文档中,它提到 IndexRoute 具有与 Route 相同的所有道具
<IndexRoute components=main: Main, side: Side />
有效!
完整代码:
React.render((
<Router>
<Route path="/" component=App >
<IndexRoute components=main: Main, side: Side />
</Route>
</Router>
), document.getElementById('app'))
Codepen:http://codepen.io/chmaltsp/pen/ZeLaPr?editors=001
干杯!
【讨论】:
【参考方案2】:来自 github 的示例是 2 年前编写的(查看 here),我不确定它与哪个特定版本相关。而且我不确定它现在是否有效(因为我也是 react 新手),但我知道您没有使用这种方法来达到这个目标,您可以使用包含 mainz
和 @ 的单独组件987654323@,这里是我的例子:
class App2 extends React.Component
render()
return (
// Your Menu.
// Your Container.
<div>
this.props.children
</div>
);
class Home extends React.Component
render()
return (<div><h1>Home</h1></div>);
class HomeSidebar extends React.Component
render()
return (<div><p>I am a sidebar</p></div>);
class HomeWithSidebar extends React.Component
render()
return (
<div>
<Home />
<HomeSidebar />
</div>
);
ReactDOM.render(
<Router history=browserHistory>
<Route path="/" component=App2>
<Route path="/a2" components=HomeWithSidebar />
</Route>
</Router>,
document.getElementById('content')
);
PS:不要忘记在您的示例中使用<Router history=browserHistory>
。
在您的示例中使用 IndexRoute
或指定另一个,例如在我的示例中使用 /a2
。
【讨论】:
【参考方案3】:我自己对路由器做出反应是新手,但我确信您使用的路由不正确。在您给出的示例中,您有 2 条不同的路由解析到相同的路径 (/):
ReactDOM.render(
<Router>
<Route path="/" component=App2>
<Route path="/" components=main: Home, sidebar: HomeSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
我相信这应该是这样的:
ReactDOM.render(
<Router>
<Route path="/" component=App2>
<IndexRoute components=main: Home, sidebar: HomeSidebar/>
<Route path="some/other/path" components=main: Home, sidebar: SomeOtherSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
【讨论】:
【参考方案4】:如果您使用的是当前版本的 react-router (v4.0.0),看起来他们取消了 Routes 上的 components 属性:https://reacttraining.com/react-router/web/api/Route
你可以在任何地方渲染路由,他们甚至有一个sidebar example,他们就是这样做的。它们有一组 Route 组件来渲染主要组件和另一组 Route 组件用于侧边栏,但两者都来自单个路由配置以保持 DRY。
要将其转换为您的代码,您可以创建一个路由配置:
const routes = [
path: '/',
sidebar: Sidebar
main: Main
];
然后在 Main.js 中
ReactDOM.render(
<Router>
<Route component=App2>
routes.map((route, index) => (
<Route
key=index
path=route.path
component=route.main
/>
))
</Route>
</Router>,
document.getElementById('content')
);
然后在 App2.js 中
class App2 extends React.Component
render()
return (
<div>
<Menu inverted vertical fixed="left">
routes.map((route, index) => (
<Route
key=index
path=route.path
component=route.sidebar
/>
))
</Menu>
<Container className="main-container">
this.props.children
</Container>
</div>
);
export default App2;
【讨论】:
唉,看来这是“我一直在阅读过时的文档”的情况。我正在使用最新版本,但一直在阅读似乎是 1.0 文档的内容。谢谢你,我会尽快尝试。【参考方案5】:我希望您知道您使用的是 react-router 1.0.x,它已经过时了。当前版本是 4.x。
以下代码完美运行(基于您提供的示例)。
let Router = ReactRouter.Router;
let RouterContext = Router.RouterContext;
let Route = ReactRouter.Route;
class App2 extends React.Component
render ()
const main, sidebar = this.props;
return (
<div>
<div className="Main">
main
</div>
<div className="Sidebar">
sidebar
</div>
</div>
)
class Home extends React.Component
render()
return (
<div><h1>Home</h1></div>
);
class HomeSidebar extends React.Component
render()
return (
<div>
<p>I'm a sidebar</p>
</div>
);
ReactDOM.render(
<Router>
<Route component=App2>
<Route path="/" components=main: Home, sidebar: HomeSidebar/>
</Route>
</Router>,
document.getElementById('content')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/1.0.3/ReactRouter.min.js"></script>
<div id="content"></div>
【讨论】:
你之所以投反对票是因为你指出某人要朝着正确的方向思考。以上是关于反应路由器混乱的主要内容,如果未能解决你的问题,请参考以下文章
React + Backbone,目标容器不是 DOM 元素