React native 使用react本机元素更改主题不起作用?

React native 使用react本机元素更改主题不起作用?,react-native,react-native-elements,React Native,React Native Elements,我一直在与react native elements合作。我想在我的应用程序中实现暗模式,但由于某些原因,当我的上下文状态发生变化时,我无法使中的主题道具发生变化 这是我的背景,我有我的黑暗主题和光明主题对象。我还有一个使用useState的LightTheEstate,这样我可以从子组件设置该状态 import React, { createContext, useState, useEffect } from "react"; import { AsyncStorage } from "re

我一直在与react native elements合作。我想在我的应用程序中实现暗模式,但由于某些原因,当我的上下文状态发生变化时,我无法使
中的主题道具发生变化

这是我的背景,我有我的黑暗主题和光明主题对象。我还有一个使用useState的
LightTheEstate
,这样我可以从子组件设置该状态

import React, { createContext, useState, useEffect } from "react";
import { AsyncStorage } from "react-native";

import { ThemeProvider } from "react-native-elements";
import lightTheme from "../themes/light";
import darkTheme from "../themes/dark";

export const ThemeModeContext = createContext();

export const ThemeContextProvider = (props) => {
  const [lightThemeState, setLightThemeState] = useState(true);

  const saveThemeState = async () => {
    if (lightThemeState) {
      await AsyncStorage.removeItem("lightThemeState");
    } else {
      await AsyncStorage.setItem(
        "lightThemeState",
        JSON.stringify(lightThemeState)
      );
    }
  };

  const getThemeState = async () => {
    currentMode = await AsyncStorage.getItem("lightThemeState");

    if (currentMode) {
      setLightThemeState(JSON.parse(currentMode));
    }
  };

  useEffect(() => {
    saveThemeState();
  }, [lightThemeState]);

  useEffect(() => {
    getThemeState();
  }, []);

  const currentTheme = lightThemeState ? lightTheme : darkTheme;

  console.log("LIGHT THEME STATE", lightThemeState); 
// When I log this after I used the setLigthThemeState in a child component. It gives the correct state ie true or false.
  console.log("COLOR OF THE THEMES BACKGROUND", currentTheme.colors.background);
// This also gives the correct background for the theme that is the "currentTheme" depending on the state. So this far, everything is correct.

  return (
    <ThemeModeContext.Provider value={[lightThemeState, setLightThemeState]}>
      <ThemeProvider theme={currentTheme}>{props.children}</ThemeProvider>
    </ThemeModeContext.Provider>
  );
};

export default ThemeContextProvider;
也许你问的黑暗主题和光明主题有问题?否,如果我将状态从true更改为false并重新加载应用程序。它起作用了。 不知何故,
中的主题没有更新。有人能解释一下原因吗?

您不能使用React原生元素动态更改主题。不幸的是,这一点在任何地方都没有被记录下来——这是一个重要的观点,因为大多数RNE用户都认为他们可以在运行时动态地更改整个主题(嗯,我做到了)

关于React Native Elements github,有几个已经解决的问题提到了这一点。 例如(2019年1月),其中一名开发人员表示:

目前这是不可能的。ThemeProvider不允许对其道具进行运行时更改。这是因为对ThemeProvider道具的更改将触发树下所有组件的重新加载

更新可以动态更改主题,但必须使用本机元素提供的HOC(例如,调用withTheme提供的updateTheme函数)。有一点额外的接线,但这是可行的。您可以在接近顶层的位置包装HOC,以便主题更新传播到所有子级。

您不能使用React原生元素动态更改主题。不幸的是,这一点在任何地方都没有被记录下来——这是一个重要的观点,因为大多数RNE用户都认为他们可以在运行时动态地更改整个主题(嗯,我做到了)

关于React Native Elements github,有几个已经解决的问题提到了这一点。 例如(2019年1月),其中一名开发人员表示:

目前这是不可能的。ThemeProvider不允许对其道具进行运行时更改。这是因为对ThemeProvider道具的更改将触发树下所有组件的重新加载

更新可以动态更改主题,但必须使用本机元素提供的HOC(例如,调用withTheme提供的updateTheme函数)。有一点额外的接线,但这是可行的。您可以将HOC包装在接近顶层的位置,以便主题更新传播到所有子级。

确切地说。 只是想补充一点,也可以使用
useContext

如果您将组件包装为具有提供程序的级别,然后在希望能够更改主题的子组件中使用
useContext
钩子,则可以提取
updateTheme
,如下所示:

const{theme,updateTheme}=useContext(ThemeContext)

这与starlabs的答案相同,但却是另一种方法,也是我做ut的方法。

没错。 只是想补充一点,也可以使用
useContext

如果您将组件包装为具有提供程序的级别,然后在希望能够更改主题的子组件中使用
useContext
钩子,则可以提取
updateTheme
,如下所示:

const{theme,updateTheme}=useContext(ThemeContext)


这与starlabs的答案相同,但又是另一种方法,也是我使用ut的方法。

为了使用react原生元素,我尝试动态更新它,但由于它在楼上的指定位置,更新它的唯一方法是这种方法,这是我第一次被迫以这种方式使用消费者XD:

//App.js
import 'react-native-gesture-handler';
import React from "react";
import { Provider } from "react-redux";
import { store } from "./redux";
import { TranslationProvider, ColorProvider } from "./context";
import { ThemeProvider } from "react-native-elements";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { appTheme as theme } from './theme';
import App from "./navigation";
import ThemeConsumer from "./components/consumers/themeConsumer";

    export default () =>
        <Provider store={store}>
            <SafeAreaProvider>
                <TranslationProvider>
                    <ColorProvider>
                        <ThemeProvider theme={theme}>
                            <ThemeConsumer>
                                <App />
                            </ThemeConsumer>
                        </ThemeProvider>
                    </ColorProvider>
                </TranslationProvider>
            </SafeAreaProvider>
        </Provider>
    
    

//themeConsumer.js

import React, { useContext, useEffect } from 'react';
import { ThemeContext } from "react-native-elements";
import { color } from '../../colors';
import { useTheme } from '../../context';

export default ({ children }) => {
    const { updateTheme } = useContext(ThemeContext);
    const { isDarkMode } = useTheme();
    useEffect(() => {
        updateTheme({ colors: color });
    }, [isDarkMode()])
    return (
        <>
            {children}
        </>
    )
}
//App.js
导入“反应本机手势处理程序”;
从“React”导入React;
从“react redux”导入{Provider};
从“/redux”导入{store};
从“/context”导入{TranslationProvider,ColorProvider};
从“react native elements”导入{ThemeProvider};
从“react native safe area context”导入{SafeAreaProvider};
从“/theme”导入{appTheme as theme};
从“/navigation”导入应用程序;
从“/components/consumers/ThemeConsumer”导入经济消费者;
导出默认值()=>
//themeConsumer.js
从“React”导入React,{useContext,useEffect};
从“react native elements”导入{ThemeContext};
从“../../colors”导入{color};
从“../../context”导入{useTheme};
导出默认值({children})=>{
const{updateTheme}=useContext(ThemeSecontext);
const{isDarkMode}=useTheme();
useffect(()=>{
更新名称({colors:color});
},[IsDakMode()])
返回(
{儿童}
)
}

为了使用react本机元素,我尝试动态更新它,但由于它位于最高层,所以更新它的唯一方法是这种方式,这是我第一次被迫以这种方式使用使用者XD:

//App.js
import 'react-native-gesture-handler';
import React from "react";
import { Provider } from "react-redux";
import { store } from "./redux";
import { TranslationProvider, ColorProvider } from "./context";
import { ThemeProvider } from "react-native-elements";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { appTheme as theme } from './theme';
import App from "./navigation";
import ThemeConsumer from "./components/consumers/themeConsumer";

    export default () =>
        <Provider store={store}>
            <SafeAreaProvider>
                <TranslationProvider>
                    <ColorProvider>
                        <ThemeProvider theme={theme}>
                            <ThemeConsumer>
                                <App />
                            </ThemeConsumer>
                        </ThemeProvider>
                    </ColorProvider>
                </TranslationProvider>
            </SafeAreaProvider>
        </Provider>
    
    

//themeConsumer.js

import React, { useContext, useEffect } from 'react';
import { ThemeContext } from "react-native-elements";
import { color } from '../../colors';
import { useTheme } from '../../context';

export default ({ children }) => {
    const { updateTheme } = useContext(ThemeContext);
    const { isDarkMode } = useTheme();
    useEffect(() => {
        updateTheme({ colors: color });
    }, [isDarkMode()])
    return (
        <>
            {children}
        </>
    )
}
//App.js
导入“反应本机手势处理程序”;
从“React”导入React;
从“react redux”导入{Provider};
从“/redux”导入{store};
从“/context”导入{TranslationProvider,ColorProvider};
从“react native elements”导入{ThemeProvider};
从“react native safe area context”导入{SafeAreaProvider};
从“/theme”导入{appTheme as theme};
从“/navigation”导入应用程序;
从“/components/consumers/ThemeConsumer”导入经济消费者;
导出默认值()=>
import React, { useContext, useState } from "react";
import { StyleSheet, View, Text } from "react-native";
import { LayoutView, ContainerView } from "../../components/styles";
import { ThemeModeContext } from "../../../store/themeStore";
import { Card, ListItem, Avatar, ThemeContext } from "react-native-elements";

import CustomButton from "../../components/CustomButton";

const INITIAL_PERSONAL_INFO_STATE = {
  name: "",
  username: "",
  profileImage: "",
  favoriteDestinations: [],
};

const MoreModal = (props) => {
  const [personalInfo, setPersonalInfo] = useState(INITIAL_PERSONAL_INFO_STATE);

  const [lightThemeState, setLightThemeState] = useContext(ThemeModeContext);
  const { theme } = useContext(ThemeContext);
  const { navigate } = props.navigation;

  const primaryColor = theme.colors.background;

  console.log("COLOR IN COMPONENT", primaryColor);
// The color is from the previous theme and even thou the state has changed in the state below
  console.log("LIGHT THEME STATE IN COMPONENT", lightThemeState);

  return (
    <LayoutView primaryColor={theme.colors.background}>
      <ContainerView>
        <View>
        </View>
        <Card
          title={"Settings"}
        >
          <ListItem
            title="Light mode"
            switch={{
              value: lightThemeState,
              onValueChange: (value) => setLightThemeState(value), 
// Here is where I set lighThemeState to false in my context

            }}
            bottomDivider
        </Card>
      </ContainerView>
      <CustomButton title={"Sign in"}></CustomButton>
    </LayoutView>
  );
};

export default MoreModal;

//App.js
import 'react-native-gesture-handler';
import React from "react";
import { Provider } from "react-redux";
import { store } from "./redux";
import { TranslationProvider, ColorProvider } from "./context";
import { ThemeProvider } from "react-native-elements";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { appTheme as theme } from './theme';
import App from "./navigation";
import ThemeConsumer from "./components/consumers/themeConsumer";

    export default () =>
        <Provider store={store}>
            <SafeAreaProvider>
                <TranslationProvider>
                    <ColorProvider>
                        <ThemeProvider theme={theme}>
                            <ThemeConsumer>
                                <App />
                            </ThemeConsumer>
                        </ThemeProvider>
                    </ColorProvider>
                </TranslationProvider>
            </SafeAreaProvider>
        </Provider>
    
    

//themeConsumer.js

import React, { useContext, useEffect } from 'react';
import { ThemeContext } from "react-native-elements";
import { color } from '../../colors';
import { useTheme } from '../../context';

export default ({ children }) => {
    const { updateTheme } = useContext(ThemeContext);
    const { isDarkMode } = useTheme();
    useEffect(() => {
        updateTheme({ colors: color });
    }, [isDarkMode()])
    return (
        <>
            {children}
        </>
    )
}