使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
当前回答
随着React Router v4即将推出,现在有了一种新的实现方式。
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
react lego是一个示例应用程序,展示了如何使用/更新react router,它包括导航应用程序的示例功能测试。
其他回答
这可能不是最好的方法,但。。。使用react router v4,下面的TypeScript代码可以为一些人提供一些想法。
在下面的渲染组件(例如LoginPage)中,可以访问router对象,只需调用router.transitionTo('/home')即可导航。
导航代码取自。
“react router”:“^4.0.0-2”,“反应”:“^15.3.1”,
从“react Router/BrowserRouter”导入路由器;从“react History/BrowserHistory”导入{History};从“history/createBrowserHistory”导入createHistory;consthistory=createHistory();接口MatchWithPropsInterface{component:React.component的类型,router:路由器,历史:历史,确切地?:任何图案:字符串}类MatchWithProps扩展React.Component<MatchWithPropsInterface,any>{render(){返回(<Match{…this.props}render={(matchProps)=>(React.createElement(this.props.component,this.props))}/>)}}ReactDOM.渲染(<路由器>{({路由器})=>(<div><MatchWithProps justly pattern=“/”component={LoginPage}router={router}history={history}/><MatchWithProps pattern=“/login”component={LoginPage}router={router}history={history}/><MatchWithProps pattern=“/home”component={homepage}router={router}history={history}/><缺少组件={NotFoundView}/></div>)}</路由器>,document.getElementById('app'));
React路由器v6+答案
TL;DR:您可以使用新的useNavigate钩子。
import { useNavigate } from "react-router-dom";
function Component() {
let navigate = useNavigate();
// Somewhere in your code, e.g. inside a handler:
navigate("/posts");
}
useNavigate钩子返回一个可用于编程导航的函数。
反应路由器文档中的示例
import { useNavigate } from "react-router-dom";
function SignupForm() {
let navigate = useNavigate();
async function handleSubmit(event) {
event.preventDefault();
await submitForm(event.target);
navigate("../success", { replace: true });
// replace: true will replace the current entry in
// the history stack instead of adding a new one.
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
React Router 5.1.0+应答(使用钩子和React>16.8)
您可以使用Functional Components上的useHistory挂钩,并以编程方式导航:
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React Router 4.0.0+答案
在4.0及以上版本中,将历史记录用作组件的道具。
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
注意:如果<Route>未呈现组件,则此.props.history不存在。您应该使用<Route path=“…”component={YourComponent}/>在YourComponent中具有this.props.history
React路由器3.0.0+答案
在3.0及以上版本中,将路由器用作组件的道具。
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React路由器2.4.0+答案
在2.4及以上版本中,使用更高阶的组件将路由器作为组件的道具。
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React Router 2.0.0+答案
此版本与1.x向后兼容,因此无需升级指南。仅仅通过这些例子就足够了。
也就是说,如果您希望切换到新模式,路由器内有一个browserHistory模块,您可以使用
从“react router”导入{browserHistory}
现在,您可以访问浏览器历史记录,因此可以执行推送、替换等操作。例如:
browserHistory.push('/some/path')
进一步阅读:历史和航行
React Router 1.x.x答案
我不会详细介绍升级。您可以在《升级指南》中阅读相关内容
这个问题的主要变化是从导航混合到历史。现在它使用浏览器历史记录API来更改路由,因此我们将从现在开始使用pushState()。
下面是使用Mixin的示例:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
请注意,此历史记录来自rackt/History项目。不是来自React Router本身。
如果您出于某种原因(可能是因为ES6类)不想使用Mixin,那么您可以从this.props.history中访问从路由器获得的历史记录。它将仅对路由器渲染的组件可用。因此,如果您想在任何子组件中使用它,则需要通过props将其作为属性传递。
您可以在他们的1.0.x文档中阅读有关新版本的更多信息
下面是一个关于在组件外部导航的帮助页面
它建议获取一个引用history=createHistory(),并对其调用replaceState。
React路由器0.13.x答案
我也遇到了同样的问题,只能通过带有react路由器的Navigation mixin找到解决方案。
我是这样做的
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
我能够在不需要访问.context的情况下调用transitionTo()
或者你可以试试ES6高级课程
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React路由器Redux注意:如果您使用的是Redux,还有一个项目叫做React Router Redux为您提供redux绑定ReactRouter,使用与React Redux会
React Router Redux有一些可用的方法,允许从内部动作创建者进行简单的导航。对于在React Native中拥有现有架构的人来说,这些模式尤其有用,并且他们希望在React Web中以最小的样板开销使用相同的模式。
探索以下方法:
推(位置)替换(位置)go(数字)goBack()goForward()
以下是Redux Thunk的用法示例:
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
上面已经提到,我们可以使用useNavigate()在上一次更新React Router V6(不包括useHistory)中导航
import { useNavigate } from 'react-router-dom';
const myComponent = () => {
const navigate = useNavigate();
navigate('my_url');
...
}
但我在这里找不到的是调用导航出React组件,就像将redux saga函数中的页面导航到另一个页面。以防万一,如果你有同样的问题,这是我发现的。
在根组件中(我称之为<App/>)
import { useNavigate } from 'react-router-dom';
import useBus from 'use-bus';
const App = () => {
const navigate = useNavigate();
useBus('@@ui/navigate', (action) => navigate(action.payload.url), []);
...
}
脱离React组件(在我的例子中是redux saga函数)
import { dispatch } from 'use-bus';
dispatch({ type: '@@ui/navigate', payload: { url: '/404' } });
希望有帮助!
如果您使用的是更新版本的React,那么使用“useHistory”钩子是最好的选择。
警告:此答案仅涵盖1.0之前的ReactRouter版本之后,我将用1.0.0-rc1用例更新这个答案!
你也可以在没有混合的情况下这样做。
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
有上下文的问题是,除非在类上定义contextType,否则它是不可访问的。
至于什么是上下文,它是一个对象,就像props一样,从父对象传递给子对象,但它是隐式传递的,不需要每次都重新声明props。看见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html