Ionic - Routerlink 不触发生命周期事件
Ionic - Routerlink not triggering Lifecycle events
我正在努力处理与 RouterLink 一起使用的 Ionic 生命周期事件。
我的应用程序数据在 JSON 文件中,该文件在加载页面时使用 url 参数呈现每个项目。我需要按钮转到下一个或上一个项目并刷新页面内容,即:
- 我在项目 1 (/lecture/item1) => 单击下一步 => routerLink(/lecture/item2)
- 我在项目 1 (/lecture/item1) => 单击上一个 => routerLink(/lecture/item0)
这意味着每次我移动到一个页面时,我都需要从 url (
/lecture/:param
) 获取参数并更新页面数据。
我面临的问题是 RouterLink 没有触发任何页面离开生命周期,所以我的状态没有改变,而且,我无法清除状态(我可以通过 href 参数来完成,但整个应用程序是刷新)。
我在这方面发现了类似的主题,但其中一些已 outdated/still 打开:
Routerlink bug github.
是否有任何way/workaround重新加载组件并更新传递不同参数的状态?
我已经尝试使用 useHistory 挂钩,history.replace (Source) 和 routerDirection="back" 但其中 none 会触发离页挂钩。我也尝试用 Switch 替换 IonRouterOutlet,但这意味着没有一些重要的离子特性。
提前致谢!!
这里摘录一段代码供参考:
lectures.json(对象数组)
{
"list" : [ {} ]
}
App.tsx
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main">
<Menu />
<IonRouterOutlet id="main">
<Route path="/" exact>
<Redirect to="/lectures" />
</Route>
<Route path="/lectures" exact component={Home}></Route>
<Route path="/lectures/:name" exact>
<Lecture />
</Route>
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</IonApp>
Lecture.tsx
const Page: React.FC = () => {
const [lecturaIndex, setLecturaIndex] = useState<number>(0);
const [btnLinks, setBtnLinks] = useState<{next?: string , prev?: string }>({});
useIonViewDidEnter(()=>{
// Gets page params and use them to find current item in data json
let current;
current = lectures.list.find(lecture => lecture.title === match.params.name);
setLecturaIndex(current.id);
// Set next and prev buttons url for routerLink
setBtnLinks({
next: current.id < 13 ? `/lectures/${languages.list[current.id+1].title}` : '/lectures',
prev: current.id > 0 ? `/lectures/${languages.list[current.id-1].title}` : '/lectures'
});
// function that Enables/disables navigation buttons depending on current index. ie: if i=0; can't go back
indexCheck(current);
})
// THESE ARE NEVER TRIGGERED WHEN GOING TO NEXT PARAM (/lectures/:param)
useIonViewWillLeave(()=>{
console.log('will leave lecture');
})
useIonViewDidLeave(()=>{
console.log('did leave lecture');
})
return(
<IonPage>
<IonContent>
<IonButton
disabled={nextBtnDisable}
routerLink={btnLinks.next}
routerDirection="back"
>
NEXT
</IonButton>
</IonContent>
</IonPage>
)
}
通常,依赖于路由匹配参数的 useEffect
足以发出副作用,例如重新获取相关数据。
here 描述的离子 useIonViewWillEnter
和 useIonViewDidEnter
挂钩基本上是安装生命周期挂钩,如果您已经在视图中,它们似乎不会触发,并且仅更改 URL 路径参数。将逻辑移动到 useEffect
挂钩,当组件安装 和 时,当其任何指定的依赖项更新时调用该挂钩。
示例:
useEffect(() => {
// business logic to handle name param changes
}, [match.params.name]);
如果匹配参数未定义,那么您可以使用可选链接运算符来防止 null/undefined 对象访问。
useEffect(() => {
// business logic to handle name param changes
}, [match?.params?.name]);
更新
似乎 useIonViewWillEnter
和 useIonViewDidEnter
钩子 do 也采用依赖数组并在内部实现 useEffect
勾。 (之前应该多挖一点)
export const useIonViewWillEnter = (callback: LifeCycleCallback, deps: any[] = []) => {
const context = useContext(IonLifeCycleContext);
const id = useRef<number | undefined>();
id.current = id.current || Math.floor(Math.random() * 1000000);
useEffect(() => {
callback.id = id.current!;
context.onIonViewWillEnter(callback);
}, deps);
};
export const useIonViewDidEnter = (callback: LifeCycleCallback, deps: any[] = []) => {
const context = useContext(IonLifeCycleContext);
const id = useRef<number | undefined>();
id.current = id.current || Math.floor(Math.random() * 1000000);
useEffect(() => {
callback.id = id.current!;
context.onIonViewDidEnter(callback);
}, deps);
};
那么 useEffect
钩子就没有必要了。
useIonViewDidEnter(() => {
// business logic to handle name param changes
}, [match?.params?.name]);
我正在努力处理与 RouterLink 一起使用的 Ionic 生命周期事件。
我的应用程序数据在 JSON 文件中,该文件在加载页面时使用 url 参数呈现每个项目。我需要按钮转到下一个或上一个项目并刷新页面内容,即:
- 我在项目 1 (/lecture/item1) => 单击下一步 => routerLink(/lecture/item2)
- 我在项目 1 (/lecture/item1) => 单击上一个 => routerLink(/lecture/item0)
这意味着每次我移动到一个页面时,我都需要从 url (
/lecture/:param
) 获取参数并更新页面数据。 我面临的问题是 RouterLink 没有触发任何页面离开生命周期,所以我的状态没有改变,而且,我无法清除状态(我可以通过 href 参数来完成,但整个应用程序是刷新)。 我在这方面发现了类似的主题,但其中一些已 outdated/still 打开: Routerlink bug github.
是否有任何way/workaround重新加载组件并更新传递不同参数的状态?
我已经尝试使用 useHistory 挂钩,history.replace (Source) 和 routerDirection="back" 但其中 none 会触发离页挂钩。我也尝试用 Switch 替换 IonRouterOutlet,但这意味着没有一些重要的离子特性。
提前致谢!!
这里摘录一段代码供参考:
lectures.json(对象数组)
{
"list" : [ {} ]
}
App.tsx
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main">
<Menu />
<IonRouterOutlet id="main">
<Route path="/" exact>
<Redirect to="/lectures" />
</Route>
<Route path="/lectures" exact component={Home}></Route>
<Route path="/lectures/:name" exact>
<Lecture />
</Route>
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</IonApp>
Lecture.tsx
const Page: React.FC = () => {
const [lecturaIndex, setLecturaIndex] = useState<number>(0);
const [btnLinks, setBtnLinks] = useState<{next?: string , prev?: string }>({});
useIonViewDidEnter(()=>{
// Gets page params and use them to find current item in data json
let current;
current = lectures.list.find(lecture => lecture.title === match.params.name);
setLecturaIndex(current.id);
// Set next and prev buttons url for routerLink
setBtnLinks({
next: current.id < 13 ? `/lectures/${languages.list[current.id+1].title}` : '/lectures',
prev: current.id > 0 ? `/lectures/${languages.list[current.id-1].title}` : '/lectures'
});
// function that Enables/disables navigation buttons depending on current index. ie: if i=0; can't go back
indexCheck(current);
})
// THESE ARE NEVER TRIGGERED WHEN GOING TO NEXT PARAM (/lectures/:param)
useIonViewWillLeave(()=>{
console.log('will leave lecture');
})
useIonViewDidLeave(()=>{
console.log('did leave lecture');
})
return(
<IonPage>
<IonContent>
<IonButton
disabled={nextBtnDisable}
routerLink={btnLinks.next}
routerDirection="back"
>
NEXT
</IonButton>
</IonContent>
</IonPage>
)
}
通常,依赖于路由匹配参数的 useEffect
足以发出副作用,例如重新获取相关数据。
here 描述的离子 useIonViewWillEnter
和 useIonViewDidEnter
挂钩基本上是安装生命周期挂钩,如果您已经在视图中,它们似乎不会触发,并且仅更改 URL 路径参数。将逻辑移动到 useEffect
挂钩,当组件安装 和 时,当其任何指定的依赖项更新时调用该挂钩。
示例:
useEffect(() => {
// business logic to handle name param changes
}, [match.params.name]);
如果匹配参数未定义,那么您可以使用可选链接运算符来防止 null/undefined 对象访问。
useEffect(() => {
// business logic to handle name param changes
}, [match?.params?.name]);
更新
似乎 useIonViewWillEnter
和 useIonViewDidEnter
钩子 do 也采用依赖数组并在内部实现 useEffect
勾。 (之前应该多挖一点)
export const useIonViewWillEnter = (callback: LifeCycleCallback, deps: any[] = []) => { const context = useContext(IonLifeCycleContext); const id = useRef<number | undefined>(); id.current = id.current || Math.floor(Math.random() * 1000000); useEffect(() => { callback.id = id.current!; context.onIonViewWillEnter(callback); }, deps); }; export const useIonViewDidEnter = (callback: LifeCycleCallback, deps: any[] = []) => { const context = useContext(IonLifeCycleContext); const id = useRef<number | undefined>(); id.current = id.current || Math.floor(Math.random() * 1000000); useEffect(() => { callback.id = id.current!; context.onIonViewDidEnter(callback); }, deps); };
那么 useEffect
钩子就没有必要了。
useIonViewDidEnter(() => {
// business logic to handle name param changes
}, [match?.params?.name]);