当我在导航中的某个地方路由时,我想在屏幕显示之前执行一个函数。。。此函数将更改应用程序的主题。NavigationContainer上确实有onStateChange
,但我需要一个类似onBeforeStateChange(): { nextRoute, currentRoute }
的侦听器函数
路由场景示例:
- 开始于:主页(主题:主页-颜色:黑色、白色(
- 路线:Profilepage(它们:Profile-颜色:蓝色、白色(
- 返回路线:主页(主题:主页-颜色:黑色、白色(
我已经能够使用NavigationContainer.onStateChange
道具复制此功能,它允许我使用以下逻辑根据路线更改主题:
<NavigationContainer
ref={navigationRef}
onReady={() =>
(routeNameRef.current = navigationRef.current.getCurrentRoute().name)
}
onStateChange={() => {
/**
* The below logic ensures the right theme is being used.
* This func can hold any GOOGLE ANALYTICS methods.
*/
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current.getCurrentRoute().name;
if (
previousRouteName !== currentRouteName &&
AVAILABLE_THEMES.includes(currentRouteName)
) {
setTheme(currentRouteName);
}
routeNameRef.current = currentRouteName;
}}>
这段代码工作得很好,只是主题更改有延迟。新主题是在状态更改时设置的,而不仅仅是在更改之前。如果我能够在NavigationContainer中运行与componentWillReceiveProps类似的功能,那么这将允许我在下一条路线显示之前更改主题(消除看起来很难看的主题更改延迟(
setTheme();
方法来自HOC组件。这是我正在使用的HOC和React上下文提供程序:
import React, { createContext, useContext, useState } from 'react';
import { THEMES } from 'theme/colors';
const ThemeContext = createContext();
const ThemeContextProvider = ({ children }) => {
const [themeID, setThemeID] = useState(THEMES[0].key);
return (
<ThemeContext.Provider value={{ themeID, setThemeID }}>
{children}
</ThemeContext.Provider>
);
};
const withTheme = (Component) => {
return (props) => {
const { themeID, setThemeID } = useContext(ThemeContext);
const getTheme = (tID) => THEMES.find((t) => t.key === tID);
const setTheme = (tID) => setThemeID(tID);
let theme = getTheme(themeID);
// Return a default theme if none was found
if (!theme) {
theme = THEMES[0];
}
return (
<Component {...props} themes={THEMES} theme={theme} setTheme={setTheme} />
);
};
};
我的主页和Profilepage都包含在withTheme
HOC中。目前,主题将在导航状态更改后更改,我希望能够在导航进入下一个屏幕之前更改主题(而不是在实际显示下一屏幕后更改(
问题:
- 我是否在react导航级别上尝试处理主题处理过复杂的事情,或者我是否走对了路线
您可以在调用prop.navigation.anavigation("主页"(.之前,通过调用更改主题颜色的函数来更改主题
如果您使用按钮/可触摸/可按下进行导航。在调用navigation.anavigation((函数之前,您可以在onPress道具中调用主题更改函数。这肯定会在加载新屏幕之前更改主题。如果在屏幕更改之前主题发生更改。您可以在主题函数之前粘贴加载指示器函数。因此,结构如下:
- setIsLoading(true(//显示加载指示器
- changeTheme((//在显示加载指示器时更改主题
- navigationnavigation("主页"(//更改屏幕
为了确保它们按正确的顺序运行,由于JavaScript是异步的,您可以使函数Promises或回调,以便它们在运行下一个函数之前等待当前函数的返回。
或者,您可以将此功能添加到每个屏幕,一旦屏幕加载,它就会运行:
import { useFocusEffect } from '@react-navigation/native';
useFocusEffect(
React.useCallback(() => {
const changeTheme = changeThemeColor(() => { ...Theme function logic... });
return () => changeTheme();
}, [])
);
此功能在屏幕聚焦时运行。
您还可以添加加载指示器,以便在加载屏幕后执行主题函数时隐藏屏幕,并在主题函数返回后渲染屏幕。这可以通过React.useState((轻松实现