提问人:Dave 提问时间:11/18/2023 最后编辑:jonrsharpeDave 更新时间:11/18/2023 访问量:44
如果 URL 哈希值发生变化,如何激活效果?
How do I activate an effect if the URLs hash changes?
问:
我正在使用 Ionic 7 和 React 18。如果 URL 的哈希部分发生变化,我想在我的容器中激活一个不同的组件。我试过这样做:
const MyContainer: React.FC<ContainerProps> = () => {
...
useEffect(() => {
// Set step based on the hash in the URL
const hash = window.location.hash.substring(1); // Remove the '#' from the hash
switch (hash) {
...
case 'message':
dispatch(setStep(StepsEnum.Message));
break;
}
}, []);
...
{step === StepsEnum.Name && <MyFirstComponent />}
{step === StepsEnum.Address && <MySecondComponent />}
{step === StepsEnum.Message && <MyThirdComponent />}
</IonContent>
</IonPage>
)
}
export default MyContainer
不幸的是,当我在浏览器中输入不同的哈希值时,什么也没发生(至少,我没有看到我的useEffect被调用)。是否可以根据 URL 的哈希值激活不同的组件?
答:
1赞
Ori Drori
11/18/2023
#1
除非你使用路由器,如 React Router,它提供了跟踪 URL 更改的钩子,否则你需要显式侦听事件。hashchange
示例(单击链接):
const { useState, useEffect } = React;
const MyContainer = () => {
const [hash, setHash] = useState();
useEffect(() => {
const handleUrlChange = () => {
setHash(window.location.hash.substring(1));
};
window.addEventListener('hashchange', handleUrlChange);
return () => {
window.removeEventListener('hashchange', handleUrlChange);
};
}, []);
return (
<div>
<a href="#1">1</a>
<a href="#2">2</a>
<a href="#3">3</a>
<a href="#4">4</a>
{hash}
</div>
);
};
ReactDOM
.createRoot(root)
.render(<MyContainer />);
a {
margin: 0.5em;
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
您可以将哈希跟踪代码提取到钩子(预期):useHash
const { useState, useEffect } = React;
const useHash = () => {
const [hash, setHash] = useState();
useEffect(() => {
const handleUrlChange = () => {
setHash(window.location.hash.substring(1));
};
window.addEventListener('hashchange', handleUrlChange);
return () => {
window.removeEventListener('hashchange', handleUrlChange);
};
}, []);
return hash;
};
const MyContainer = () => {
const hash = useHash();
return (
<div>
<a href="#1">1</a>
<a href="#2">2</a>
<a href="#3">3</a>
<a href="#4">4</a>
{hash}
</div>
);
};
ReactDOM
.createRoot(root)
.render(<MyContainer />);
a {
margin: 0.5em;
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
现在你可以用以下方式触发你的生产:useEffect
hash
useHash
const MyContainer = () => {
const hash = useHash();
useEffect(() => {
switch (hash) {
...
case 'message':
dispatch(setStep(StepsEnum.Message));
break;
}
}, [hash]);
评论
0赞
Dave
11/20/2023
你提到“除非你使用react router......”我确实安装了“@ionic/react-router”(7.0.0),这是否允许我做一些与您上面详述的不同的事情?
0赞
Dave
11/20/2023
总而言之,我会使用 useLocation 钩子来监听 URL 更改并等到检测到哈希更改?
0赞
Ori Drori
11/21/2023
并使用哈希作为 的依赖项。useEffect
评论