使用 react-router 触发路由更改动作
Triggering action on route change with react-router
我正在用 React、redux 和 react-router 创建一个小应用程序。
我有一个包含在 <Link />
中的项目列表,当我单击其中一个时,我希望将项目设置为触发 [=23] 之前的状态 currentItem
=] 行动。有一个操作可以做到这一点 - selectItem(item)
- 但我不知道如何触发它。
我应该在 componentWillUnmount
上触发吗?在那种情况下 - 我如何找出点击了什么项目?我应该创建一个 <Link onClick={}/>
处理程序来调度操作吗?
项目页面随后将检查是否设置了 currentItem,如果没有设置则可能从后端获取它。
我发现使用 Link 效果很好。
您可以使用它来访问事件和原始组件的值。像这样:
<Link to={address} onClick={actions.handlerFunction}>
其中 handlerFunction 是 redux 动作创建者。然后在您的 handlerFunciton 中,您可以像这样访问事件和元素的值:event.target.value
。
您的动作创建器应如下所示:
export function handlerFunction(event) {
return {
type: 'CHANGE_SOMETHING',
prop: event.target.value
}
}
然后你可以在你的减速器中设置状态。
如果您不需要事件,但想将一些数据传递给动作创建者,您可以像这样使用它:
<Link to={address} onClick={() => actions.handlerFunction(someData)}>
将 to
属性 添加到 Link 很重要,它会更新您在地址栏中看到的地址。
您也可以使用 "root" 组件中的 componentWillReceiveProps
来执行此操作,并将 nextProps
与 this.props
进行比较。
路由器将 props 传递给组件(location、history 等),您可以处理这些。
例如:
ReactDOM.render(
<Router>
<Route path="/" component={App}/>
</Router>,
document.getElementById('root')
);
并且在您的 App 组件中:
componentWillReceiveProps(nextProps) {
if (nextProps.location.pathname != this.props.location.pathname) {
// do stuff
}
P.S。我还是个react小白,如果对这个方法有什么意见或者建议欢迎评论。
使用上次 React 更新的新 useEffect
和 useRef
助手,您可以这样做:
import React, { useEffect, useRef } from 'react';
import { withRouter, RouteComponentProps } from 'react-router';
function Bob({ location: { key } }: RouteComponentProps) {
const oldURL = useRef(key); // key is a unique identifier set by react-router
useEffect(() => {
if (oldURL.current !== key) {
// trigger your action here
}
oldURL.current = key; // refresh the oldURL after every render
});
}
export default withRouter(Bob);
useRef
需要将旧值保存在内存中。
然后,你比较旧的location.key
和新的
如果比较location.pathname
,则不会检测到搜索参数的变化,因为路径名只取域名和搜索参数之间的文本:
htpp://foo.bar/products?filterBy=price
^ ^ ^
domain name | pathname | search params
通过比较 location.key
,即使 filterBy
发生变化,您的操作也会被触发。
不适用于 location.pathname
.
我正在用 React、redux 和 react-router 创建一个小应用程序。
我有一个包含在 <Link />
中的项目列表,当我单击其中一个时,我希望将项目设置为触发 [=23] 之前的状态 currentItem
=] 行动。有一个操作可以做到这一点 - selectItem(item)
- 但我不知道如何触发它。
我应该在 componentWillUnmount
上触发吗?在那种情况下 - 我如何找出点击了什么项目?我应该创建一个 <Link onClick={}/>
处理程序来调度操作吗?
项目页面随后将检查是否设置了 currentItem,如果没有设置则可能从后端获取它。
我发现使用 Link 效果很好。
您可以使用它来访问事件和原始组件的值。像这样:
<Link to={address} onClick={actions.handlerFunction}>
其中 handlerFunction 是 redux 动作创建者。然后在您的 handlerFunciton 中,您可以像这样访问事件和元素的值:event.target.value
。
您的动作创建器应如下所示:
export function handlerFunction(event) {
return {
type: 'CHANGE_SOMETHING',
prop: event.target.value
}
}
然后你可以在你的减速器中设置状态。
如果您不需要事件,但想将一些数据传递给动作创建者,您可以像这样使用它:
<Link to={address} onClick={() => actions.handlerFunction(someData)}>
将 to
属性 添加到 Link 很重要,它会更新您在地址栏中看到的地址。
您也可以使用 "root" 组件中的 componentWillReceiveProps
来执行此操作,并将 nextProps
与 this.props
进行比较。
路由器将 props 传递给组件(location、history 等),您可以处理这些。
例如:
ReactDOM.render(
<Router>
<Route path="/" component={App}/>
</Router>,
document.getElementById('root')
);
并且在您的 App 组件中:
componentWillReceiveProps(nextProps) {
if (nextProps.location.pathname != this.props.location.pathname) {
// do stuff
}
P.S。我还是个react小白,如果对这个方法有什么意见或者建议欢迎评论。
使用上次 React 更新的新 useEffect
和 useRef
助手,您可以这样做:
import React, { useEffect, useRef } from 'react';
import { withRouter, RouteComponentProps } from 'react-router';
function Bob({ location: { key } }: RouteComponentProps) {
const oldURL = useRef(key); // key is a unique identifier set by react-router
useEffect(() => {
if (oldURL.current !== key) {
// trigger your action here
}
oldURL.current = key; // refresh the oldURL after every render
});
}
export default withRouter(Bob);
useRef
需要将旧值保存在内存中。
然后,你比较旧的location.key
和新的
如果比较location.pathname
,则不会检测到搜索参数的变化,因为路径名只取域名和搜索参数之间的文本:
htpp://foo.bar/products?filterBy=price
^ ^ ^
domain name | pathname | search params
通过比较 location.key
,即使 filterBy
发生变化,您的操作也会被触发。
不适用于 location.pathname
.