为什么useEffect不会在window.location.pathname更改时运行?我loc只登录一次。
当路径名更改而没有任何其他库时,如何运行useEffect?
useEffect(() => {
const loc = window.location.pathname
console.log({ loc })
}, [window.location.pathname])
Run Code Online (Sandbox Code Playgroud)
Scr*_*jet 25
奇怪的是没有人提到这一点,但是您可以通过react-router-dom使用useLocation钩子来获取位置。所以你可以在依赖数组中使用它。
文档在这里
const location = useLocation();
useEffect(() => {
console.log(location);
}, [location.pathname]);
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个仅用于使用 web 进行反应的解决方案,并且您正在使用react-router-domweb 库。
如果您想在没有安装该库的情况下实现此目的,并且其他答案对您不起作用,您需要执行以下操作:-
export const LocationContext = React.createContext<LocationContextObject>(
null!
);
Run Code Online (Sandbox Code Playgroud)
使用位置设置此上下文提供程序的值
导航时,您需要使用新位置更新此上下文值,(创建自定义导航功能并在任何地方使用它)
** 灵感来自于remix-run/react-router (react-router-dom)的源码
Raf*_*ora 14
创建一个钩子,例如:
const useReactPath = () => {
const [path, setPath] = React.useState(window.location.pathname);
const listenToPopstate = () => {
const winPath = window.location.pathname;
setPath(winPath);
};
React.useEffect(() => {
window.addEventListener("popstate", listenToPopstate);
return () => {
window.removeEventListener("popstate", listenToPopstate);
};
}, []);
return path;
};
Run Code Online (Sandbox Code Playgroud)
然后在您的组件中像这样使用它:
const path = useReactPath();
React.useEffect(() => {
// do something when path changes ...
}, [path]);
Run Code Online (Sandbox Code Playgroud)
当然,您必须在顶级组件中执行此操作。
我改编了 Rafael Mora 的答案,使其适用于整个位置对象,并且还使用该方法在 Next.js 应用程序的前端工作useIsMounted,并添加了打字稿类型。
hooks/useWindowLocation.ts
import useIsMounted from './useIsMounted'
import { useEffect, useState } from 'react'
const useWindowLocation = (): Location|void => {
const isMounted = useIsMounted()
const [location, setLocation] = useState<Location|void>(isMounted ? window.location : undefined)
useEffect(() => {
if (!isMounted) return
const setWindowLocation = () => {
setLocation(window.location)
}
if (!location) {
setWindowLocation()
}
window.addEventListener('popstate', setWindowLocation)
return () => {
window.removeEventListener('popstate', setWindowLocation)
}
}, [isMounted, location])
return location
}
export default useWindowLocation
Run Code Online (Sandbox Code Playgroud)
hooks/useIsMounted.ts
import { useState, useEffect } from 'react'
const useIsMounted = (): boolean => {
const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
setIsMounted(() => true)
}, [])
return isMounted
}
export default useIsMounted
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7797 次 |
| 最近记录: |