基于类的项目中的反应原生黑暗主题
Posted
技术标签:
【中文标题】基于类的项目中的反应原生黑暗主题【英文标题】:React-native dark theme in class based project 【发布时间】:2021-08-26 12:53:27 【问题描述】:我无法为我的 react-native 应用添加深色主题支持。
主题上下文.js
import React from 'react';
const themes =
dark:
backgroundColor: 'gray',
backgroundCard: '#25282c',
color: 'white'
,
light:
backgroundColor: 'yellow',
backgroundCard: '#fff',
color: 'black'
const initialState =
dark: false,
theme: themes.light,
toggle: () =>
const ThemeContext = React.createContext(initialState)
function ThemeProvider(children)
const [dark, setDark] = React.useState(false) // Default theme is light
// Toggle between dark and light modes
const toggle = () =>
setDark(!dark)
// Filter the styles based on the theme selected
const theme = dark ? themes.dark : themes.light
return(
<ThemeContext.Provider value=theme, dark, toggle>
children
</ThemeContext.Provider>
)
export ThemeProvider, ThemeContext
App.js
import 'react-native-gesture-handler';
import React, Component from 'react';
import LogBox, SafeAreaView, StyleSheet, ScrollView, Button, View, Text, Image, Alert, TouchableOpacity, TouchableHighlight from 'react-native';
import NavigationContainer from '@react-navigation/native';
import createStackNavigator from '@react-navigation/stack';
import Home from './Home.js';
import Settings from './Settings.js';
import Icon from 'react-native-vector-icons/FontAwesome';
import ThemeProvider from './theme-context'
const Stack = createStackNavigator();
function LogoTitle()
return (
<Image
style= width: 140, height: 50
source=require('./images/title.png')
/>
);
// ------------------App-----------------------------
class App extends Component
render()
return (
<ThemeProvider>
<NavigationContainer>
<Stack.Navigator
screenOptions=
headerStyle:
backgroundColor: '#f4f4f4',
,
headerTintColor: 'gray',
headerTitleStyle:
fontWeight: 'bold',
,
>
<Stack.Screen
name="Home"
component=Home
options=( navigation, route ) => (
headerTitle: props => <LogoTitle ...props />,
headerRight: () => (
<Icon.Button
name="cog"
backgroundColor="transparent"
size=25
onPress=() => navigation.navigate('Settings')
title="Settings"
color="gray"
/>
),
)
/>
<Stack.Screen
name="Settings"
component=Settings
/>
</Stack.Navigator>
</NavigationContainer>
</ThemeProvider>
);
export default App;
home.js
import 'react-native-gesture-handler';
import React, Component, useContext from 'react';
import LogBox, SafeAreaView, StyleSheet, ScrollView, View from 'react-native';
import Card from 'react-native-elements';
import CardOne from './Components/CardOne.js';
import CardTwo from './Components/CardTwo.js';
import CardThree from './Components/CardThree.js';
import CardFour from './Components/CardFour.js';
import ThemeProvider from './theme-context';
// ------------------App-----------------------------
class Home extends Component
constructor(props)
super(props);
// ...
render()
return (
<ThemeProvider>
<View>
<SafeAreaView>
<ScrollView >
<CardOne/>
<CardTwo/>
<CardThree/>
<CardFour />
</ScrollView>
</SafeAreaView>
</View>
</ThemeProvider>
);
export default Home;
接下来我想在我的一个组件上使用上下文
import React, Component, useContext from 'react';
import Card from 'react-native-elements';
import StyleSheet, View, Text, Image, Alert, TouchableOpacity from 'react-native';
import ThemeContext from 'ResCalc/theme-context';
const dark, theme, toggle = useContext(ThemeContext);
class CardOne extends Component
constructor(props)
super(props);
...
render()
return (
<Card containerStyle=styles.card>
<View>
<Switch
onChange=toggle value = dark />
</View>
</Card>
);
const styles = StyleSheet.create(
card:
backgroundColor: theme.backgroundColor,
borderColor: "#D1D1D6",
borderWidth: 2,
borderRadius: 5,
shadowOffset: width: 5, height: 5, ,
shadowColor: '#D1D1D6', // #D1D1D6
shadowOpacity: 1.0,
shadowRadius: 2,
elevation: 3,
);
export default CardOne
我想我必须在基于类的变体中使用 useContext 挂钩,但我就是不知道该怎么做。
希望有人能帮我解决这个问题:)
【问题讨论】:
Hooks 只能在函数组件中使用。 ***.com/a/61498084/5793132 这能回答你的问题吗? Passing props into external stylesheet in React Native? 如何使用 Class.contextType 调用切换方法? 【参考方案1】:您可以将您的样式定义为一个函数,然后将您的主题注入其中。
const styles = (theme) => StyleSheet.create(
card:
backgroundColor: theme.backgroundColor,
borderColor: "#D1D1D6",
borderWidth: 2,
borderRadius: 5,
shadowOffset: width: 5, height: 5, ,
shadowColor: '#D1D1D6', // #D1D1D6
shadowOpacity: 1.0,
shadowRadius: 2,
elevation: 3,
);
在您的组件中:
class CardOne extends Component
static contextType = ThemeContext;
render()
// Pass theme context to styles functiion
return (
<Card containerStyle=styles(this.context.theme).card>
<View>
<Switch
onChange=toggle value = dark />
</View>
</Card>
);
【讨论】:
您先生,成功了!非常感谢! Promise Rejection "toggle is not defined" 出现错误。请帮我如何更改切换模式? @GamiNileshtoggle
在 OPs ThemeProvider
中定义以上是关于基于类的项目中的反应原生黑暗主题的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Google Services Analytics 编译反应原生项目