问题描述
我想将主题状态存储在应用程序中,以便所选主题在应用程序关闭后将保持不变。我有两个文件,一个是具有导航的App.js文件,另一个是具有抽屉内容以及主题开关的DrawerContent.js文件。 toggleTheme
通过DrawerContent
传递到useContext
。
import {
NavigationContainer,DefaultTheme as NavigationDefaultTheme,DarkTheme as NavigationDarkTheme
} from '@react-navigation/native';
import {
Provider as PaperProvider,DefaultTheme as PaperDefaultTheme,DarkTheme as PaperDarkTheme
} from 'react-native-paper';
import AsyncStorage from '@react-native-community/async-storage';
const THEME_KEY = 'theme_color';
export default function App() {
const [isDarkTheme,setIsDarkTheme] = useState(false);
{/* Themes */ }
const CustomDefaultTheme = {
...NavigationDefaultTheme,...PaperDefaultTheme,colors: {
...NavigationDefaultTheme.colors,...PaperDefaultTheme.colors,background: '#ffffff',text: '#333333',tab: '#0789DC'
}
}
const CustomDarkTheme = {
...NavigationDarkTheme,...PaperDarkTheme,colors: {
...NavigationDarkTheme.colors,...PaperDarkTheme.colors,background: '#333333',text: '#ffffff',tab: '#2c3e50'
}
}
const theme = isDarkTheme ? CustomDarkTheme : CustomDefaultTheme;
// AsyncSotrage
const storeTheme = async (key,isDarkTheme) => {
try {
await AsyncStorage.setItem(THEME_KEY,JSON.stringify(isDarkTheme))
setIsDarkTheme(isDarkTheme);
console.log(isDarkTheme)
} catch (error) {
alert(error);
}
}
const getTheme = async () => {
try {
const savedTheme = await AsyncStorage.getItem(THEME_KEY)
if (savedTheme !== null) {
setIsDarkTheme(JSON.parse(savedTheme));
}
} catch (error) {
alert(error);
}
}
const authContext = useMemo(() => ({
toggleTheme: () => {
setIsDarkTheme(isDarkTheme => !isDarkTheme);
// storeTheme(isDarkTheme => !isDarkTheme);
console.log(isDarkTheme);
}
}),[]
);
useEffect(() => {
getTheme();
// Fetch the token from storage then navigate to our appropriate place
const bootstrapAsync = async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem(USER_TOKEN)
if (userToken !== null) {
setUserToken(JSON.parse(userToken))
}
} catch (e) {
alert(e)
}
// After restoring token,we may need to validate it in production apps
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
dispatch({ type: 'RESTORE_TOKEN',token: userToken });
};
bootstrapAsync();
},[]);
return (
<PaperProvider theme={theme}>
<AuthContext.Provider value={authContext}>
<NavigationContainer theme={theme}>
...
</NavigationContainer>
</AuthContext.Provider>
</PaperProvider>
)
}
这是DrawerContent代码。
import {
useTheme,Avatar,Title,Caption,Paragraph,Drawer,Text,TouchableRipple,Switch
} from 'react-native-paper';
export function DrawerContent(props) {
const paperTheme = useTheme();
const { signOut,toggleTheme } = React.useContext(AuthContext);
return (
<View style={{ flex: 1 }}>
<DrawerContentScrollView>
<View style={styles.drawerContent}>
...
<Drawer.Section title="Preferences">
<TouchableRipple onPress={() => { toggleTheme() }}>
<View style={styles.preference}>
<Text>Dark Theme</Text>
<View pointerEvents="none">
<Switch
value={paperTheme.dark}
/>
</View>
</View>
</TouchableRipple>
</Drawer.Section>
</View>
</DrawerContentScrollView>
</View>
)
}
解决方法
也许AsyncStorage的有效同步访问可以解决您的问题。建议您使用react-native-easy-app开放源代码库react-native-easy-app,通过它您可以访问AsyncStorage中的任何数据(如内存对象)。
对于特定用法,也许您可以在Project StorageController中引用Sample_Hook文件