React Router - &#34; <router>可能只有一个子元素&#34;错误

时间:2017-12-06 14:59:30

标签: reactjs react-router react-redux react-router-v4

在我的React应用中,我想将我的主路由器连接到Redux,以便我可以访问存储在那里的一些值,但我收到错误"A <Router> may have only one child element"。我已经看到其他人遇到过这个问题,但解决方案总是涉及将路线包裹在<div><Switch>中,我已经完成了......我不太确定在这种情况下修复它。

理想情况下,这就是我想要实现的目标 - 这是routes/index.jsx

import React from "react"
import { connect } from "react-redux"
import { Route, Switch } from "react-router"
import AppContainer from "containers/App"
import SignInRouter from "./signin-router"
import SignUpRouter from "./signup-router"
import DashboardRouter from "./dashboard-router"
import NotFound from "../components/NotFound"

const mapStateToProps = (state) => {
        return { state }
    }

const routes = (props) => (
    <AppContainer>
        <Switch>
            <Route exact path="/" component={SignInRouter} />
            <Route path={`/${props.state.state.signupPath}`} component={SignUpRouter} />
            <Route path={`/${props.state.state.dashboardPath}`} component={DashboardRouter} />
            <Route path="/*" component={NotFound} />
        </Switch>
    </AppContainer>
)

export default connect(mapStateToProps, null)(routes)

最初,这个设置如下:

const routes = (
    <AppContainer>
        // etc...
    </AppContainer>
)

但是一旦我把它改成了一个函数 - const routes = (props) => (...) - 它就破了。

我有点恼火,因为我能够通过应用程序中的其他一些路由器成功完成此操作 - 例如,这里是routes/dashboard-router.jsx

import React from "react"
import { connect } from "react-redux"
import { Switch, Route } from "react-router"
import DashboardContainer from "../containers/App/dashboard-container"
import DashboardIndex from "../components/Dashboard"
import Agendas from "../components/Dashboard/agendas"
import Meetings from "../components/Dashboard/meetings"
import Groups from "../components/Dashboard/groups"
import Account from "../components/Dashboard/account"
import NotFound from "../components/NotFound"

const mapStateToProps = (state) => {
        return { state }
    }

const DashboardRouter = (props) => (
    <DashboardContainer>
        <Switch>
            <Route exact path={`/${props.state.state.dashboardPath}`} component={DashboardIndex} />
            <Route exact path={`/${props.state.state.dashboardPath}/agendas`} component={Agendas} />
            <Route exact path={`/${props.state.state.dashboardPath}/meetings`} component={Meetings} />
            <Route exact path={`/${props.state.state.dashboardPath}/groups`} component={Groups} />
            <Route exact path={`/${props.state.state.dashboardPath}/account`} component={Account} />
            <Route path={`/${props.state.state.dashboardPath}/*`} component={NotFound} />
        </Switch>
    </DashboardContainer>
)

export default connect(mapStateToProps, null)(DashboardRouter)

并且效果很好。

为什么这是我的顶级路由器中的问题,而不是在较低级别的路由器中?我该怎么做才能解决这个问题?

有关其他参考,请参阅AppContainer<Switch>import React from "react" import { connect } from "react-redux" import { withRouter } from "react-router-dom" import Header from "components/Header" const mapStateToProps = (state) => { return { state } } const AppContainer = (props) => { return ( <div className="container"> <Header isAuthenticated={props.state.session.isAuthenticated} /> <main> {props.children} </main> </div> ) } export default withRouter(connect(mapStateToProps, null)(AppContainer)) 打包在相关路由器中:

<StaticRouter>

对于Robert Farley的评论,这是一个React / Phoenix应用程序,使用https://github.com/reph-stack/reph搭建。以下是此应用程序结构中引用containers/index.jsx的方式:

import React from "react" import { Provider } from "react-redux" import createStoreAndRouter from "store" const Index = (props) => { const { store, router } = createStoreAndRouter(props) return ( <Provider store={store}> {router} </Provider> ) } export default Index

store/index.js

import React from "react" import { createStore, combineReducers, applyMiddleware, compose } from "redux" import { ConnectedRouter, routerReducer, routerMiddleware, push } from "react-router-redux" import { Route, StaticRouter } from "react-router" import createBrowserHistory from "history/createBrowserHistory" import createMemoryHistory from "history/createMemoryHistory" import thunkMW from "redux-thunk" import routes from "routes" import reducers from "reducers" import WSActions from "actions/ws" export default function createStoreAndRouter(props) { return (typeof window !== "undefined" && typeof window === "object") ? createForBrowser() : createForServer(props) } const createForBrowser = () => { const devToolsExt = typeof window.devToolsExtension !== "undefined" ? window.devToolsExtension() : f => f const history = createBrowserHistory() const store = createStore( reducers, window.__INITIAL_STATE__, compose( applyMiddleware(thunkMW), applyMiddleware(routerMiddleware(history)), devToolsExt ) ) store.dispatch(WSActions.init()) const router = <ConnectedRouter history={history} > {routes} </ConnectedRouter> return { store, router } } const createForServer = (props) => { const history = createMemoryHistory() const store = createStore( reducers, props.initial_state, compose( applyMiddleware(thunkMW), applyMiddleware(routerMiddleware(history)) ) ) const router = <StaticRouter context={{}} location={props.location} history={history} > {routes} </StaticRouter> return { store, router } }

In [346]: df[['A','C']].T.agg(['mean','std']).T
Out[346]:
   mean       std
0   4.5  3.535534
1   8.0  0.000000
2   4.5  3.535534
3   6.0  2.828427
4   4.5  3.535534
5   4.5  4.949747
6   7.5  0.707107
7   8.5  0.707107

1 个答案:

答案 0 :(得分:0)

如果你想在一个函数中渲染它们,我认为你需要将你的路由包装在路由器中:

import { BrowserRouter } from 'react-router-dom'

const routes = (props) => (
    <AppContainer>
      <BrowserRouter>  
        <Switch>
          <Route exact path="/" component={SignInRouter} />
          <Route path={`/${props.state.state.signupPath}`} component={SignUpRouter} />
          <Route path={`/${props.state.state.dashboardPath}`} component={DashboardRouter} />
          <Route path="/*" component={NotFound} />
        </Switch>
      </BrowserRouter>
    </AppContainer>
)