BrowserRouter 不会将历史记录传递给渲染内的组件
BrowserRouter won't pass history to component inside render
React 路由器版本为 4。
这是我代码中 BrowserRouter
的用法:
import React from 'react';
import ReactDOM from 'react-dom';
import {Meteor} from 'meteor/meteor';
import {BrowserRouter, Route, Redirect, Switch} from 'react-router-dom';
import browserHistory from 'history';
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/Signup';
import MyLink from '../imports/ui/MyLink';
import NotFound from '../imports/ui/NotFound';
import Login from '../imports/ui/Login';
const history = browserHistory.createBrowserHistory();
const unathenticatedPages = ['/', '/signup'];
const athenticatedPages = ['/mylink'];
const isLoggedIn = () => {
return Meteor.userId() !== null;
};
const routes = (
<BrowserRouter>
<Switch >
<Route exact path="/" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Login/>)} />
<Route path="/signup" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Signup/>)} />
<Route path="/login" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Login/>)} />
<Route path="/mylink" render={() => (!isLoggedIn() ? <Login/> : <MyLink history={history}/>)} />
<Route path="*" component={NotFound} />
</Switch>
</BrowserRouter>
);
Tracker.autorun(() => {
const isAuthenticated = !!Meteor.userId();
console.log("isAuthenticated: ", isAuthenticated);
const pathname = history.location.pathname;
console.log("pathname: ", pathname);
const isUnathenticatedPage = unathenticatedPages.includes(pathname);
const isAthenticatedPage = athenticatedPages.includes(pathname);
if (isLoggedIn() && isUnathenticatedPage) {
history.replace('/mylink');
} else if (!isLoggedIn() && isAthenticatedPage) {
history.replace('/');
}
});
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
我遇到的问题是,当 BrowserRouter
的 history
位于 render()
内时,它们不会传递给呈现的组件,如上。 this.props.history.replace('/notfound');
在 MyLink
组件中不起作用。传递给 MyLink
组件的 history
实例似乎与 BrowserRouter
创建的实例不一样。
但是在 NotFound
中,一个 this.props.history.replace('/...');
会按预期工作。
解决方案是什么?
我认为解决方案是使用 render()
发送的函数参数中的历史对象
<Route path="/mylink" render={({history}) => (!isLoggedIn()
? <Login/>
: <MyLink history={history}/>)}
/>
React 路由器版本为 4。
这是我代码中 BrowserRouter
的用法:
import React from 'react';
import ReactDOM from 'react-dom';
import {Meteor} from 'meteor/meteor';
import {BrowserRouter, Route, Redirect, Switch} from 'react-router-dom';
import browserHistory from 'history';
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/Signup';
import MyLink from '../imports/ui/MyLink';
import NotFound from '../imports/ui/NotFound';
import Login from '../imports/ui/Login';
const history = browserHistory.createBrowserHistory();
const unathenticatedPages = ['/', '/signup'];
const athenticatedPages = ['/mylink'];
const isLoggedIn = () => {
return Meteor.userId() !== null;
};
const routes = (
<BrowserRouter>
<Switch >
<Route exact path="/" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Login/>)} />
<Route path="/signup" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Signup/>)} />
<Route path="/login" render={() => (isLoggedIn() ? <Redirect to="/mylink"/> : <Login/>)} />
<Route path="/mylink" render={() => (!isLoggedIn() ? <Login/> : <MyLink history={history}/>)} />
<Route path="*" component={NotFound} />
</Switch>
</BrowserRouter>
);
Tracker.autorun(() => {
const isAuthenticated = !!Meteor.userId();
console.log("isAuthenticated: ", isAuthenticated);
const pathname = history.location.pathname;
console.log("pathname: ", pathname);
const isUnathenticatedPage = unathenticatedPages.includes(pathname);
const isAthenticatedPage = athenticatedPages.includes(pathname);
if (isLoggedIn() && isUnathenticatedPage) {
history.replace('/mylink');
} else if (!isLoggedIn() && isAthenticatedPage) {
history.replace('/');
}
});
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
我遇到的问题是,当 BrowserRouter
的 history
位于 render()
内时,它们不会传递给呈现的组件,如上。 this.props.history.replace('/notfound');
在 MyLink
组件中不起作用。传递给 MyLink
组件的 history
实例似乎与 BrowserRouter
创建的实例不一样。
但是在 NotFound
中,一个 this.props.history.replace('/...');
会按预期工作。
解决方案是什么?
我认为解决方案是使用 render()
<Route path="/mylink" render={({history}) => (!isLoggedIn()
? <Login/>
: <MyLink history={history}/>)}
/>