使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
当前回答
上面已经提到,我们可以使用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' } });
希望有帮助!
其他回答
根据JoséAntonio Postigo和Ben Wheeler先前的回答:
新奇之处?用TypeScript编写并使用修饰符或静态属性/字段
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
无论今天安装了什么npm。
“react router”:“^3.0.0”和“@types/react router”:“^2.0.41”
更新:2022:使用useNavigate的React Router v6.6.1
useHistory()钩子现已弃用。如果您使用的是React Router 6,编程导航的正确方法如下:
import { useNavigate } from "react-router-dom";
function HomeButton() {
const navigate = useNavigate();
function handleClick() {
navigate("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
带挂钩的React Router v5.1.0
如果您使用的是React>16.8.0和功能组件,则React Router>5.1.0中有一个新的useHistory钩子。
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
反应路由器v4
使用React Router的v4,有三种方法可以用于组件内的编程路由。
使用withRouter高阶组件。使用合成并渲染<Route>使用上下文。
React Router主要是历史库的包装器。历史记录处理与浏览器窗口的交互。历史记录为您提供浏览器和哈希历史记录。它还提供了一个内存历史,对于没有全局历史的环境非常有用。这在使用Node进行移动应用程序开发(react native)和单元测试时特别有用。
历史记录实例有两种导航方法:推送和替换。如果您将历史记录视为一个访问位置数组,push将向数组中添加一个新位置,replace将用新位置替换数组中的当前位置。通常,您在导航时需要使用push方法。
在React Router的早期版本中,您必须创建自己的历史实例,但在v4中,<BrowserRouter>、<HashRouter>和<MemoryRouter>组件将为您创建浏览器、哈希和内存实例。React Router使与路由器关联的历史实例的财产和方法通过路由器对象下的上下文可用。
1.使用withRouter高阶组件
withRouter高阶组件将注入历史对象作为组件的属性。这允许您访问push和replace方法,而不必处理上下文。
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
2.使用合成并渲染<Route>
<Route>组件不仅仅用于匹配位置。您可以渲染无路径路线,它将始终与当前位置匹配。<Route>组件传递与withRouter相同的属性,因此您可以通过历史属性访问历史方法。
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
3.使用上下文*
但你可能不应该
最后一个选项是只有当您觉得使用React的上下文模型时才应该使用的选项(React的context API在v16中是稳定的)。
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1和2是实现的最简单的选择,因此对于大多数用例来说,它们是最好的选择。
上面已经提到,我们可以使用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 Router v4中,我遵循这两种方式以编程方式进行路由。
this.props.history.push(“/某物/某物”)this.props.history.replace(“/ssomething/something”)
第二个
替换历史堆栈上的当前条目
要获取道具中的历史记录,您可能必须使用
带路由器
InReact路由器v6
import { useNavigate } from "react-router-dom";
function Invoices() {
let navigate = useNavigate();
return (
<div>
<NewInvoiceForm
onSubmit={async event => {
let newInvoice = await createInvoice(event.target);
navigate(`/invoices/${newInvoice.id}`);
}}
/>
</div>
);
}
React Router v6入门
只需使用this.props.history.push('/where/to/go');