如何在 React Native Navigation v6 的 React Native class 组件中使用 context 和 useTheme?

How to use context and useTheme in React Native class components in react native navigation v6?

我知道 useContext 由于功能原因并非专门用于组件,但我正在尝试使用 ThemeContext 并且我知道这里有解决方法。我在他们使用 class 组件的地方看到了它的文档,但仍然无法理解它。

我已经包含了一个 snack example here,其中 classComponent.js 是我想要实现的。我希望它呈现与 Friends.js 相同的效果,但使用 class 组件 而不是 函数 。在同一个小吃中,我希望 toggle.js 成为 class 组件。

这是我要复制的代码。

const Toggle = (props) => {
  const { setTheme, theme } = React.useContext(ThemeContext);
  return (
   <TouchableOpacity onPress={() => setTheme(theme === DefaultTheme ? DarkTheme : DefaultTheme)}>

这是我试图在其中实现上述代码的代码。

export default class Toggle extends React.Component {
   //How can I set my state?
   state = {}
   render(){
      return(
         <TouchableOpacity onPress={() => setTheme(theme === DefaultTheme ? DarkTheme : DefaultTheme)}>
      );
   }

首先,我们将 toggle.js 转换为 class component。有两件事我们需要做,其中一件根本不明显(我不知道为什么这是必要的,但是 GitHub 上有一个旧错误,目前还没有令人满意的答案)。

  1. ThemeContext 的创建移动到它自己的文件中(我不知道为什么这是必要的;可能是因为导出必须是 default export?)。
  2. 使用 static contextType = ThemeContext
  3. 在 class 组件中绑定上下文

因此,以下将 toggle.js 转换为 class 组件。

ThemeContext.js

import React from 'react'
const ThemeContext = React.createContext();
export default ThemeContext

toggle.js

import ThemeContext from '../ThemeContext'

class Toggle extends React.Component {

  static contextType = ThemeContext

  constructor(props) {
    super(props)
  }

  render() {
      const {theme, setTheme} = this.context 

       return <TouchableOpacity onPress={() => setTheme(theme === Light ? Dark : Light)}>
        <View style={{ height: 50, width: 100, backgroundColor: 'blue', justifyContent:'center', alignItems: 'center' }}>
            <Text style={{color: 'white',fontSize: 20 }}>Toggle theme</Text>
        </View>
      </TouchableOpacity>
  }
}

export default Toggle;

由于显而易见的原因,无法在 class 组件中使用 useTheme 挂钩。 class 组件没有替代方案。

官方解决这个问题的方法是将class组件包装成一个功能组件,并将useTheme中的theme作为prop传递给class零件。这个is recommended in the documentation.

我已将其重命名为 Friends.js

import { useTheme } from '@react-navigation/native';

class Friends extends React.Component {
  render() {
    const { theme } = this.props;

    return (
      /* I would like to be able to call colors.primary and colors.secondary here rather than green and grey */
      <View style={{justifyContent: 'center', alignItems: 'center', flex: 1, backgroundColor: theme.colors.primary}}>

          <View style={{ height: 100, width: 300, backgroundColor: theme.colors.secondary, justifyContent:'center', alignItems: 'center' }}>
            <Text style={{color: "black",fontSize: 30 }}>Friends Screen</Text>
          </View>
      </View>
    );
  }
}

// Wrap and export
export default function(props) {
  const theme = useTheme();

  return <ClassComponent {...props} theme={theme} />;
}

这是一个updated snack using class components.