基于类的项目中的反应原生黑暗主题

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" 出现错误。请帮我如何更改切换模式? @GamiNilesh toggle 在 OPs ThemeProvider 中定义

以上是关于基于类的项目中的反应原生黑暗主题的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应原生中过滤FlatList中的项目

反应原生 - 有办法隐藏/显示另一个页面中的项目?

无法使用 Google Services Analytics 编译反应原生项目

反应原生问题中的条带集成

有人可以向我解释为啥我的 django 管理主题是黑暗的吗?

每行显示 2 个项目 [反应原生]