Я знаю, что useContext не предназначен специально для компонентов из-за функциональности, но я пытаюсь использовать ThemeContext, и я знаю, что здесь есть способ обойти это. Я видел документацию для него, где они используют компонент класса, но все еще не мог понять этого.
Я включил пример закуски здесь, где classComponent.js — это то, что я хочу реализовать. Я бы хотел, чтобы он отображался так же, как Friends.js, но с использованием компонент класса, а не функция. В этой же закуске я хотел бы, чтобы toggle.js был компонентом класса.
Это код, который я пытаюсь воспроизвести.
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 есть старая ошибка, на которую пока нет удовлетворительного ответа).
ThemeContext
в отдельный файл (не знаю, зачем это нужно; может потому, что экспорт должен быть default export
?).static contextType = ThemeContext
Таким образом, следующее преобразует toggle.js
в компонент класса.
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;
Использование хука useTheme
в компоненте класса невозможно по понятным причинам. Альтернативы компонентам класса нет.
Официальный способ решить эту проблему — обернуть компонент класса в функциональный компонент и передать theme
из useTheme
в качестве реквизита компоненту класса. Это рекомендуется в документации.
Я переименовал его в 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} />;
}
Вот обновленная закуска с использованием компонентов класса.
Вы можете обернуть свой компонент класса в функциональный компонент, который передает состояние темы в качестве реквизита.