Getting started with React Router



我正在尝试设置我的react应用程序。

我正在努力了解如何将路线与应用程序集成。

当我尝试在ReactDOM中使用AppRouter时,我收到一条错误消息,说我不应该在Router之外使用Route。

我不明白这个错误是什么意思。当我从提供程序中删除AppRouter行时,我可以消除错误消息,但这只会在提供程序中创建新的错误。我找不到如何开始的例子。

我的app.js有:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import AppRouter from './routers/AppRouter.js';
import { BrowserRouter } from 'react-router-dom';
import configureStore from './store/configureStore.js';
// import { startSetUsers } from './actions/users';

import 'normalize.css/normalize.css';
import './styles/styles.scss';
import './firebase/firebase';
// import * as firebaseui from 'firebaseui'
//import './playground/promises';

const store = configureStore();
const jsx = (
<Provider store={store}>
<AppRouter />
</Provider>
);
ReactDOM.render(jsx, document.getElementById('app'));

我的AppRouter有:

import React from 'react';
import { connect } from 'react-redux';
import { BrowserRouter, Route, Switch, Link, NavLink, withRouter } from 'react-router-dom';
import Header from '../components/Header.js';
import Footer from '../components/Footer.js';
import Dashboard from '../components/home/Dashboard.js';
import Landing from '../components/home/Landing.js';
import ErrorNotice from '../components/ErrorNotice.js';
import SignIn from '../components/auth/RegisterPage.js';
import Pending from '../components/auth/PendingPage.js';
import SignInSuccess from '../components/auth/SignInSuccess.js';

import Users from '../components/users/UserDashboard.js';
// this Higher Order Component wraps the app and listens for Firebase auth change state event
// when this state changes, it updates the store
import withAuthentication from '../hoc/withAuthentication';
import AuthenticatedRoute from  '../components/auth/AuthenticatedRoute';
const AppRouter = () => {
return (
<div>
<Header />
<Switch>
<Route path="/" exact={true} component={Landing} />
{/* Authentication Related routes */}
<Route path="/Signin" component={SignIn} />
{/* This route no longer required. Was used when uiConfig has a redirect URL */}
{/* <Route path="/Loading" component={SignInSuccess} /> */}
<Route path="/Pending" component={Pending} />
{/* PUBLIC ROUTES */}
<Route path="/Users" component={Users} />
<Route path="/Menu" component={Menu} />
{/* AUTHENTICATED ROUTES */}
{/* Places routes that require authenitcation here and use the AuthenticatedRoute */}
<AuthenticatedRoute path="/Dashboard" component={Dashboard} />
<Route component={ErrorNotice} />
</Switch>
<Footer />
</div>
)
}

// set up passing of store state as component props
const mapStateToProps = state => ({
authUser: state.sessionState.authUser,
});
// connect this component to the store
// wrap withRouter to ensure that Links work: => https://reacttraining.com/react-router/core/guides/redux-integration/blocked-updates
export default withRouter(connect(mapStateToProps)(AppRouter));

有人看到我哪里错了吗?

修订的AppRouter.js

import React from "react";
import { connect } from "react-redux";
import {
BrowserRouter,
Route,
Switch,
Link,
NavLink,
withRouter
} from "react-router-dom";
import Header from "../components/Header.js";
import Footer from "../components/Footer.js";
import Dashboard from "../components/home/Dashboard.js";
import Landing from "../components/home/Landing.js";
import ErrorNotice from "../components/ErrorNotice.js";
import SignIn from "../components/auth/RegisterPage.js";
import Pending from "../components/auth/PendingPage.js";
import SignInSuccess from "../components/auth/SignInSuccess.js";
import About from "../components/footerlinks/company/About.js";
import Users from "../components/users/UserDashboard.js";
// this Higher Order Component wraps the app and listens for Firebase auth change state event
// when this state changes, it updates the store
import withAuthentication from "../hoc/withAuthentication";
import AuthenticatedRoute from "../components/auth/AuthenticatedRoute";
const AppRouter = () => {
<BrowserRouter>
<div>
<Header />
<Switch>
<Route path="/" exact={true} component={Landing} />
{/* Authentication Related routes */}
<Route path="/Signin" component={SignIn} />
{/* This route no longer required. Was used when uiConfig has a redirect URL */}
{/* <Route path="/Loading" component={SignInSuccess} /> */}
<Route path="/Pending" component={Pending} />
{/* PUBLIC ROUTES */}
<Route path="/About" component={About} />
<Route path="/Users" component={Users} />
<Route path="/Menu" component={Menu} />
{/* AUTHENTICATED ROUTES */}
{/* Places routes that require authenitcation here and use the AuthenticatedRoute */}
<AuthenticatedRoute path="/Dashboard" component={Dashboard} />
<Route component={ErrorNotice} />
</Switch>
<Footer />
</div>
</BrowserRouter>;
};
// set up passing of store state as component props
const mapStateToProps = state => ({
authUser: state.sessionState.authUser
});
// connect this component to the store
// wrap withRouter to ensure that Links work: => https://reacttraining.com/react-router/core/guides/redux-integration/blocked-updates
export default connect(mapStateToProps)(AppRouter);

从导入语句中删除withRouter后的控制台错误:

Warning: Failed prop type: Invalid prop `component` of type `object` supplied to `Route`, expected `function`.
in Route (created by AppRouter)
in AppRouter (created by Connect(AppRouter))
in Connect(AppRouter)
in Provider
Warning: AppRouter(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
printWarning @ warning.js:33
warning @ warning.js:57
warnIfInvalidElement @ ReactCompositeComponent.js:51
mountComponent @ ReactCompositeComponent.js:193
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
mountComponentIntoNode @ ReactMount.js:104
perform @ Transaction.js:143
batchedMountComponentIntoNode @ ReactMount.js:126
perform @ Transaction.js:143
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
_renderNewRootComponent @ ReactMount.js:319
_renderSubtreeIntoContainer @ ReactMount.js:401
render @ ReactMount.js:422
(anonymous) @ app.js:29
__webpack_require__ @ bootstrap 8dde10c53183363cc06e:19
(anonymous) @ bundle.js:50261
__webpack_require__ @ bootstrap 8dde10c53183363cc06e:19
module.exports @ bootstrap 8dde10c53183363cc06e:62
(anonymous) @ bootstrap 8dde10c53183363cc06e:62
invariant.js:42 Uncaught Error: AppRouter(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object

我认为问题在于AppRouter没有返回任何内容。在箭头函数中,如果你写() => {statement},它会执行该语句,但如果你写了() => statement,它会返回它。因此,你应该将AppRouter修改为:

const AppRouter = () => (
<BrowserRouter>
...
</BrowserRouter>
);

有关箭头功能的更多信息:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

希望它能有所帮助。

Hi@Mel几天前我遇到了类似的问题,我解决了如下问题:

  1. index.html中,检查您的id是否为app,而不是root

  2. 修改你的app.js以具有:

    const jsx = (
    <Provider store={store}>
    <BrowserRouter>
    <AppRouter />
    </BrowserRouter>
    </Provider>
    );
    
  3. 现在,您的AppRouter需要是一个基于类的组件,因此修改后会变成如下所示:

// All your imports come here

class AppRouter extends Component {
render() {
let routes = (
<Switch>
<Route path="/" exact={true} component={Landing} />
<Route path="/Signin" component={SignIn} />
<Route path="/Pending" component={Pending} />
<Route path="/Users" component={Users} />
<Route path="/Menu" component={Menu} />
<AuthenticatedRoute path="/Dashboard" component={Dashboard} />
<Route component={ErrorNotice} />
</Switch>
);
return (
<div>
<Header />
{routes}
<Footer />
</div>
);
}
}
const mapStateToProps = state => ({
authUser: state.sessionState.authUser
});
export default withRouter(connect(mapStateToProps)(AppRouter));

如果您仍然面临问题,请告诉我,我可以共享更多代码。

希望它能有所帮助!快乐编码!;(

index.jsappRouter.js应该包含这种类型的写的路由

import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import store from './redux-state.js';

ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App>
<Switch>
<Route path="/" exact={true} component={Landing} />
<Route exact path="/" component={Home}/>
<Route component={Error404} />
</Switch>
</App>
</BrowserRouter>
</Provider>,
document.getElementById('appRoot'),
renderCommon
);

而在app.js中,您可以编写以下内容,它应该可以很好地工作

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
function mapStateToProps(state) {
return {};
}
function mapDispatchToProps(dispatch) {
return {};
}
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
{this.props.children}
)
}
}

只需复制并粘贴代码。它会起作用的。如果你有任何问题,请给我发短信

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Header from '../components/Header.js';
import Footer from '../components/Footer.js';
import NotFound from "../../ui/pages/notfound";
import Dashboard from '../components/home/Dashboard.js';
import Landing from '../components/home/Landing.js';
import ErrorNotice from '../components/ErrorNotice.js';
import SignIn from '../components/auth/RegisterPage.js';
import Pending from '../components/auth/PendingPage.js';
import SignInSuccess from '../components/auth/SignInSuccess.js';

import Users from '../components/users/UserDashboard.js';
// this represent ur actions
import { togglemenu } from "../../../actions/index";
import { bindActionCreators } from 'redux';

class AppRouter extends Component {
render() {
return (
<BrowserRouter>
<Header />
<div>
<Switch>
<Route path="/" exact={true} component={Landing} />
<Route path="/Signin" exact={true} component={SignIn} />
<Route path="/Pending" exact={true} component={Pending} />
{/* PUBLIC ROUTES */}
<Route path="/Users" exact={true} component={Users} />
<Route path="/Menu" exact={true} component={Menu} />
<Route component={NotFound} />
</Switch>
</div>
<Footer />
</BrowserRouter>
)
}
}

function mapStateToProps(state) {
return {
// ur redux state
home: state.home
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
// ur redux action
togglemenu: togglemenu
}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(AppRouter);

最新更新