为什么我的全能路线不能在我的Switch中工作?

时间:2017-06-20 02:10:47

标签: reactjs react-router react-jsx

我有一个现有的应用程序,我正在尝试从react-route v2升级到react-router v4。如果没有其他匹配,我该如何渲染一个包罗万象的路线?这是我到目前为止所做的:

<Switch>
  <Route exact path="/" component={Home} />
  <About />
  <Route component={Splat} />
</Switch>

<About />组件包含自己的路由:

<div>
  <Route path="/foo/one" component={One} />
  <Route path="/bar/two" component={Two} />
</div>

通过此设置,我无法呈现Splat路由,因为它认为About是匹配的。

此Codepen应说明我的问题 -  https://codepen.io/justinpincar/pen/xrqQEZ

2 个答案:

答案 0 :(得分:3)

问题是您在About内呈现Switch。并不是它认为About是匹配的,而是About没有一直呈现的匹配条件。 About组件包含静态JSX,它将出现在除/之外的所有路径上,因为它是第一条路径。当您从About替换JSX时,您得到:

<Switch>
  <Route exact path="/" component={Home} />
  <div>
    <h1>About</h1>
    <p>This is about</p>
    <Route path="/foo/one" component={One} />
    <Route path="/bar/two" component={Two} />
  </div>      
  <Route component={Splat} />
</Switch>

此处,div位于Switch内。如果您有div和此处的路线,则Switch一次只能呈现一个孩子 - 就像转换一样。

因此,当您导航到/ 之外的任何其他路线时,第一条路线/不匹配,它会转到下一个孩子。下一个孩子是div,其中不是路线本身,因此没有标准来呈现。因此,它在每条路线上呈现Switch中从未到达最后一条路线,因为div没有路径,因此它会被静态渲染,因此会显示除/以外的所有地方。

相反,请为About组件设置一条路线,使其具有渲染位置的路径标准:

<Route path="/about" component={About} />

然后,因为您的OneTwo路由不应该嵌套(因为它们不共享公共路径/about),所以通过将它们移出来为它们提供自己的路由About。然后在OneTwo组件中,渲染AboutHere's an updated Codepen

答案 1 :(得分:0)

https://github.com/ReactTraining/react-router/issues/5261

根据他们的建议,要么:

class About extends React.Component {
  render() {
    return (
      <div>
        {this.props.children}
      </div>
    )
  }
}

const One = (props) => (
  <About>
    <div>Page One</div>
  </About>
)

const Two = (props) => (
  <About>
    <div>Page Two</div>
  </About>
)

const App = () => (
  <Switch>
    <Route exact path='/' component={Home} />
    <Route exact path='/foo/one' component={One} />
    <Route exact path='/bar/two' component={Two} />
    <Route component={Splat} />
  </Switch>
)

或者:

// you have to use component, not render or children
const AboutRoute = ({ component:Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    <About>
      <Component {...props} />
    </About>
  )} />
)

const One = (props) => (
  <div>Page One</div>
);

const Two = (props) => (
  <div>Page Two</div>
);


const App = () => (
  <Switch>
    <Route exact path='/' component={Home} />
    <AboutRoute exact path='/foo/one' component={One} />
    <AboutRoute exact path='/bar/two' component={Two} />
    <Route component={Splat} />
  </Switch>
)

感谢您的快速回答,非常有帮助!