React-router 4中IndexRoute的替代方案是什么?

3

我正在学习一门课程,作者编写了一些使用 react-router 版本 3 进行路由的代码。

<Router history={browserHistory} >
  <Route path="/" component={Main}>
      <IndexRoute component={PhotoGrid}></IndexRoute>
      <Route path="/view/:postId" component={Single}>
   </Route>
</Router>

在学习课程(我正在使用router版本4)时,我了解到现在<IndexRoute>已经不存在了。我搜索了替代方案,并发现exact是可替代的。但是我不知道如何使用exact来满足这个要求。作者希望Main组件始终存在于DOM中,并且根据URL只有子组件应该改变(即SinglePhotoGrid)。
我尝试了下面的代码,当然是错误的:

 <BrowserRouter>
    <Switch>
      <Route path="/" component={Main} />
      <Route exact path="/" component={PhotoGrid} />
      <Route path="/veiw/:postId" component={Single} />
    </Switch>
  </BrowserRouter>    

我的组件包括:

class Main extends React.Component {
  render() {
    return (
        <div>
          <h1>
            <Link to="/">Reduxtagram</Link>
          </h1>
          {React.cloneElement(this.props.children, this.props)}
        </div>           
    );
  }
}

class PhotoGrid extends React.Component {
  render() {
    return <div className="photo-grid">PhotoGrid</div>;
  }
}

class Single extends React.Component {
  render() {
    return <div className="single-photo">Single</div>;
  }
}
2个回答

2
Switch组件只会渲染第一个匹配的Route
您可以将Main组件作为常规组件使用,并将Switch用作其children
<BrowserRouter>
  <Main>
    <Switch>
      <Route exact path="/" component={PhotoGrid} />
      <Route path="/view/:postId" component={Single} />
    </Switch>
  </Main>
</BrowserRouter>

我使用了 Switch 来避免错误 A <Router> may have only one child element。但是从你的代码来看,我又遇到了这个错误。我认为我们需要将所有的组件/路由嵌套在一个单独的标签内,并放在 BrowserRouter 中。 - The Coder
使用此代码,MainPhotoGrid 是相邻的组件。要求是,PhotoGrid 应该是 Main 的子组件。 - The Coder
此外,当我将URL更改为“/view/1234”时,“Single”组件未被渲染。 - The Coder
@TheCoder 我更新了答案。path="/view/:postId" 仍然匹配 /view/1234 - Tholle
1
我在 Main 组件中遗漏了 {React.cloneElement(this.props.children, this.props)},这导致子组件没有被添加。已经添加到问题中了。谢谢您的帮助。 - The Coder
显示剩余2条评论

0

我知道这是一个老问题,但我正在跟随同一课程,并决定更新所有的库。基本上,我不得不重新构建这个应用程序,像这样:

reduxtagram.js:

import React from 'react';
import {render} from 'react-dom';
import App from './components/App';
import {Provider} from 'react-redux';
import store from './store';
// import css
import css from './styles/style.styl';

// import react router deps

const router = (
    <Provider store={store}>
      <App/>
    </Provider>
)

render(router , document.getElementById('root'));

main.js:

import React, { Component } from 'react';
import {Link} from 'react-router-dom';
import PhotoGrid from './PhotoGrid';
import Single from './Single';
import {Router, Route} from 'react-router-dom';
import {history} from '../store';

export default class Main extends Component {
render() {
    return (
        <div>
            <Router history={history}>
                <Route
                path="/"
                render={(routeProps) => (
                    <h1>
                        <Link to='/'>Reduxstagram </Link>
                    </h1>
                )}/>

                <Route
                path="/grid"
                render={(routeProps) => (
                    <PhotoGrid {...routeProps} {...this.props} />
                )}/>

                <Route
                path="/grid/view/:postID"
                render={(routeProps) => (
                    <Single {...routeProps} {...this.props} />
                )}/>

            </Router>
        </div>
    )
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接