反应路由器混乱

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】:

看起来你需要使用&lt;IndexRoute /&gt; 组件而不是&lt;Route /&gt; 来让组件支持工作。在 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:不要忘记在您的示例中使用&lt;Router history=browserHistory&gt;。 在您的示例中使用 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 元素

反应路由器/反应查询不会取消/发出导航请求 - 反应/打字稿

我应该使用快速、客户端反应路由器还是服务器端反应路由器?

在拍摄多张照片时反应原生路由器通量和反应原生相机问题

javascript 反应页面转换(假设反应路由器v4)

使用反应路由器 4 不渲染反应组件