Scr*_*pts 56 javascript reactjs react-router-dom
我正在尝试将旧的 React router dom 代码迁移到 v6,我想知道如何监听路由更改,我现在正在使用useHistory
const history = useHistory()
//then
history.listen(...)
Run Code Online (Sandbox Code Playgroud)
我确实阅读了新文档,并且发现它useHistory已更改为useNavigate
const navigate = useNavigate()
//then
navigate.listen(...) // listen is not a function
Run Code Online (Sandbox Code Playgroud)
你能帮我找到一种方法来监听 v6 中的路由变化吗
// This is a React Router v6 app
import { useNavigate } from "react-router-dom";
function App() {
let navigate = useNavigate();
function handleClick() {
navigate("/home");
}
return (
<div>
<button onClick={handleClick}>go home</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*dez 38
从文档(https://reactrouter.com/en/main/hooks/use-location)中,使用此钩子
let location = useLocation();
React.useEffect(() => {
ga('send', 'pageview');
}, [location]);
Run Code Online (Sandbox Code Playgroud)
Dre*_*ese 28
该navigate函数是一个函数,而不是像旧react-router-dom版本 5 的history对象那样的对象。
您仍然可以创建自定义history对象,但需要创建自定义路由器才能使用它。这允许您导入对象 history并创建侦听器。
创建一个自定义路由器示例,使用更高级别的路由器之一作为示例,了解它们如何管理位置和状态,即BrowserRouter:
const CustomRouter = ({ history, ...props }) => {
const [state, setState] = useState({
action: history.action,
location: history.location
});
useLayoutEffect(() => history.listen(setState), [history]);
return (
<Router
{...props}
location={state.location}
navigationType={state.action}
navigator={history}
/>
);
};
Run Code Online (Sandbox Code Playgroud)
在您的代码中创建自定义history对象以供新的自定义路由器和其他组件使用。确保您已history@5安装为项目依赖项。这与 RRDv6 使用的版本相同。如果您需要安装它,请运行npm i history@5将其添加到项目的依赖项中。
const history = createBrowserHistory();
export default history;
Run Code Online (Sandbox Code Playgroud)
使用您的路由器并将您的历史对象传递给它。
import CustomRouter from '../CustomRouter';
import history from '../myHistory';
...
<CustomRouter history={history}>
....
</CustomRouter>
Run Code Online (Sandbox Code Playgroud)
在您想要侦听位置更改的组件中,导入您的历史对象并listen像之前一样调用回调。
import history from '../myHistory';
...
useEffect(() => {
const unlisten = history.listen((location, action) => {
// ... logic
});
return unlisten;
}, []);
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以创建自己的自定义useHistory挂钩,仅返回历史对象。
react-router-dom已开始HistoryRouter为这样的用例导出 a 。您无需导入低级Router并实现内部逻辑,而是导入unstable_HistoryRouter as HistoryRouter并传递自定义历史对象(内存、哈希等)。
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
import history from "../myHistory";
...
<HistoryRouter history={history}>
....
</HistoryRouter>
Run Code Online (Sandbox Code Playgroud)
如果您使用 RRDv6.4+ 并且不使用数据路由器,那么好消息是至少仍然通过 RRDv6.8.0unstable_HistoryRouter导出。您可以在此处跟踪存储库中提交的问题。
如果您使用数据路由器,那么新的“不稳定”方法是navigate直接使用路由器对象的附加函数。
例子:
const CustomRouter = ({ history, ...props }) => {
const [state, setState] = useState({
action: history.action,
location: history.location
});
useLayoutEffect(() => history.listen(setState), [history]);
return (
<Router
{...props}
location={state.location}
navigationType={state.action}
navigator={history}
/>
);
};
Run Code Online (Sandbox Code Playgroud)
我在使用history.listen6.4 和 6.8 版本之间的解决方案时得到了好坏参半的结果,因此最好关注相关问题,以了解 RRD 维护者所说的当前访问“历史记录”的“不稳定”方法。
小智 12
要添加到接受的答案(无法评论,没有足够的代表点),如果导航卸载了您尝试调用的组件,则通过依赖项数组中带有 location.pathname 的 useEffect 订阅历史记录将不起作用使用效果来自。
在react-router-dom v6.8.0甚至更早的版本中,尝试将侦听器附加到history,将引发错误:A history only accepts one active listener。
我了解到这react-router-dom似乎也在次要版本之间引入了很多变化,所以你应该使用像不安全和不稳定这样的词,比如unstable_HistoryRouter特别严重。如果你不是很幸运的话,它们迟早会破裂。
就我而言,我必须升级才能获得重新引入的可选路由参数,而UNSAFE_NavigationContext我的前同事决定使用,但不再工作了。
因此,这是一种高级方法,它允许您侦听路由器历史堆栈上的操作,而无需自己将另一个侦听器附加到路由器。这很好,因为默认情况下它已经有一个侦听器,并且它只是没有公开,但从它派生的操作是公开的,这就足够了。
在下面的示例中,我们对每个更改中的更改做出反应location,我们检查它是否是由于某个POP操作(例如,使用浏览器的后退按钮时触发)引起的,然后执行任何操作。
import { useEffect } from "react";
import {
Location,
NavigationType,
useLocation,
useNavigationType,
} from "react-router-dom";
export const useBackListener = (callback: () => void) => {
const location: Location = useLocation();
const navType: NavigationType = useNavigationType();
useEffect(() => {
if (navType === "POP" && location.key !== "default") {
if (someCondition === true) callback();
else {
doSomethingElse();
}
}
}, [location]);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
67177 次 |
| 最近记录: |