React Native Paper 全局主题配置、跨组件状态共享与主题切换方案
实现方案
你已经在根组件外层套了PaperProvider,只需要补充下面两步即可实现全局主题同步切换:
1. 子组件获取当前主题
react-native-paper 内置了useThemeHook,所有在PaperProvider包裹范围内的函数组件,直接调用即可拿到当前生效的主题配置,不需要手动传参:
import { useTheme } from 'react-native-paper'; function AnalyticsScreen() { // 直接获取当前主题 const theme = useTheme(); return ( <SafeAreaView style={styles.container}> <Header leftComponent={() => renderLogoIcon()} rightComponent={{ icon: 'more-vert', color: theme.colors.primary, size: 30, iconStyle: { color: theme.colors.primary } }} centerComponent={{ text: 'Analytics', style: { color: theme.colors.primary, fontSize: 20 } }} containerStyle={{ backgroundColor: '#212121', borderBottomWidth: 0, height: 80 }} /> <StatusBar style="auto" /> </SafeAreaView> ); }
如果是类组件无法使用Hook,可以用内置的withTheme高阶组件包裹,主题会通过props注入:
import { withTheme } from 'react-native-paper'; class YourClassComponent extends React.Component { render() { const { theme } = this.props; // 后续直接使用theme即可 } } export default withTheme(YourClassComponent);
2. 实现全局主题切换
你需要自定义Context把修改主题的方法暴露给下层组件,修改App组件代码如下:
// 首先创建全局主题Context export const ThemeContext = React.createContext({ theme: yellowDark, toggleTheme: () => {}, }); // 可以提前定义多套主题 const blueDark = { ...DefaultTheme, roundness: 2, colors: { ...DefaultTheme.colors, primary: '#2196F3', } }; export default class App extends React.Component { state = { theme : yellowDark, isYellowTheme: true } // 切换主题的方法 toggleTheme = () => { this.setState({ theme: this.state.isYellowTheme ? blueDark : yellowDark, isYellowTheme: !this.state.isYellowTheme }) } render() { return ( {/* 注入主题和切换方法到全局Context */} <ThemeContext.Provider value={{ theme: this.state.theme, toggleTheme: this.toggleTheme }}> <PaperProvider theme={this.state.theme}> {/* 原有NavigationContainer、Tab导航代码保持不变 */} </PaperProvider> </ThemeContext.Provider> ); } }
之后在任意子组件内需要触发主题切换时,直接从Context取toggleTheme方法调用即可:
import { useContext } from 'react'; import { ThemeContext } from './App'; // 按实际路径导入 import { Button } from 'react-native-paper'; function ExampleComponent() { const { toggleTheme } = useContext(ThemeContext); return <Button onPress={toggleTheme} mode="contained">切换主题</Button> }
注意事项
所有用到主题色的位置不要写死色值,统一从theme对象中读取,切换主题时所有组件会自动重渲染更新样式。
内容的提问来源于stack exchange,提问作者Hypo
相关产品推荐
相关产品推荐

