我正在用React native编写应用程序,遇到一个问题-该应用程序将具有多个屏幕(我使用react-navigation和react-navigation-tabs)以及由以下两个主题管理的两种颜色主题(浅色和深色)上下文和挂钩。我要实现的是应用程序要记住的所选主题(浅色主题将设置为默认主题,并且在切换为暗色后,仍应应用该应用程序并返回暗色主题)。
编辑#2:昨天的一个回答(由于某种原因而消失了)建议使用redux和本地存储,因此我正在编辑下面的段落以阐明情况。
最简单的方法是使用同步存储/ localStorage(我已经有使用本地存储的应用版本),但是我在网上发现的一个教程为此目的使用了用户备注挂钩,尽管它应该可以运行,不是(至少就我而言),而且我也不知道为什么...
下面的我的App.js文件:
imports ...
const TabNavigator = createBottomTabNavigator({
Home: Home,
List: List,
});
const App = createAppContainer(TabNavigator);
export default () => (
<ThemeProvider>
<App />
</ThemeProvider>
ThemeContext.js文件:
imports ...
export const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [colors, setColors] = useState(themes.lightTheme) //setting light theme as default
const value = useMemo(
() => ({
colors,
setColors,
}),
[colors, setColors],
);
return (
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);
}
和Home.js文件,带有在主题之间切换的按钮:
imports ...
export const Home = () => {
const { colors, setColors } = useContext(ThemeContext);
const toggleTheme = () => {
if (colors.type === 'light') {
setColors(themes.darkTheme);
} else {
setColors(themes.lightTheme);
}
}
return (
<>
<View style={{...styles.mainView, backgroundColor: colors.backgroundColor }}>
<Text style={{...styles.mainText, color: colors.color}}>Hello Native World</Text>
<Button title='toggle theme' onPress={toggleTheme} />
</View>
</>
)
}
const styles = StyleSheet.create({
mainView: {
paddingTop: 40,
display: 'flex',
alignItems: 'center',
},
mainText: {
fontSize: 40,
fontWeight: 'bold',
},
});
答案 0 :(得分:1)
您需要更改的密钥文件是您的上下文文件:
export const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [colors, setColors] = useState(themes.lightTheme) //setting light theme as default
const value = useMemo(
() => ({
colors,
setColors,
}),
[colors, setColors],
);
return (
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);
}
我不太了解您为什么使用useMemo
,但我会保留。乍一看,我会说不需要它,但我不知道您的应用程序。您想要的是这样的:
import AsyncStorage from '@react-community/async-storage'
export const ThemeContext = createContext()
export function usePersistedState(key, initialState) {
const [state, setState] = useState(() => {})
useEffect(() => {
async function getAndSetInitialState() {
const persistedState = await AsyncStorage.getItem(key)
if (persistedState) {
setState(JSON.parse(persistedState))
} else if (typeof initialState === 'function') {
return setState(initialState())
} else {
return setState(initialState)
}
}
getAndSetInitialState()
}, [key])
function setPersistedState(value) {
AsyncStorage.setItem(key, JSON.stringify(value))
setState(value)
}
return [state, setPersistedState]
}
export const ThemeProvider = ({ children }) => {
const [colors, setColors] = usePersistedState("your_storage_key", themes.lightTheme) //setting light theme as default
const value = useMemo(
() => ({
colors,
setColors,
}),
[colors, setColors]
)
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
}
我可能会错过一些极端情况,但是这样,您的应用程序将从存储中加载状态并将其状态保存到存储中。
编辑:我不确定useMemo
有什么帮助,AsyncStorage是最简单的imo解决方案。