-1

I am trying to update theme of my react native app using context API but it is throwing an error setThemeMode is not a function. (In 'setThemeMode(themeMode === 'light' ? 'dark': 'light')', 'setThemeMode' is "i")

I have taken refernce of following blog article https://www.smashingmagazine.com/2020/01/introduction-react-context-api/

Main Error Image

ThemeContext.js

import React from 'react';

const ThemeContext = React.createContext(['light', () => {}]);
export default ThemeContext;

App.js

    import React, {useState} from 'react';

    import Nav from './src/navigation/Nav';
    import 'react-native-gesture-handler';
    import ThemeContext from './src/context/ThemeContext';

    const App = () => {
    const [theme] = useState("light");
    return (
    <>
    <ThemeContext.Provider value={theme}>
        <Nav />
    </ThemeContext.Provider>
    </>
    );
    };

    export default App;

Settings.js

    import React, {useContext} from 'react';
    import {View, Text, TouchableHighlight, Alert} from 'react-native';
    import Icon from 'react-native-vector-icons/dist/Ionicons';

    import Switches from 'react-native-switches';

    import ThemeContext from './../context/ThemeContext';
    import AppTheme from './../Colors';

    import {
    widthPercentageToDP as wp,
    heightPercentageToDP as hp,
    } from 'react-native-responsive-screen';
    import ThemeSwitch from './ThemeSwitch';

    const Settings = () => {
    const [themeMode, setThemeMode] = useContext(ThemeContext);
    const theme = useContext(ThemeContext);
    const currentTheme = AppTheme[theme];

    return (
        <>
    <TouchableHighlight
        onPress={() => setThemeMode(themeMode === 'light' ? 'dark' : 'light')} 
        style={{
            backgroundColor: 'black',
            borderRadius: 100,
            width: wp(14),
            height: wp(14),
            justifyContent: 'center',
            alignItems: 'center',
        }}>
        <Icon name="md-arrow-round-back" size={wp(8)} color="white" />
        </TouchableHighlight>
    </>
    );
    };

    export default Settings;

Nav.js

    import React from 'react';
    import {NavigationContainer} from '@react-navigation/native';
    import {createStackNavigator} from '@react-navigation/stack';

    import Welcome from './../components/Welcome';
    import Settings from './../components/Settings';
    import Main from './../components/Main';

    const Stack = createStackNavigator();

    const Nav = () => {
    return (
        <NavigationContainer>
        <Stack.Navigator
            screenOptions={{
            headerShown: false,
            }}>
            <Stack.Screen name="Main" component={Main} />
            <Stack.Screen name="Settings" component={Settings} />
            <Stack.Screen name="Welcome" component={Welcome} />
        </Stack.Navigator>
        </NavigationContainer>
    );
    };

    export default Nav;

Colors.js

        const AppTheme = {
    light: {
        name: 'light',
        textColor: 'black',
        backgroundColor: 'white',
    },
    dark: {
        name: 'dark',
        textColor: 'white',
        backgroundColor: 'black',
    },
    };

    export default AppTheme;

I want to dynamically update context. Pardon me for such silly bug but I am new to react and Js. I have attached the issue image. I think I am doing something wrong with useContext because when I try to console.log(ThemeContext) it was showing undefined instead of light.

Shrikant Jha
  • 73
  • 11

2 Answers2

0

In App js ... You have to set the theme mode like const [themeMode, setThemeMode] = useState('light');

then <ThemeContext.Provider value={themeMode,setThemeMode}>

then wherever you want to update the value ... you can access it const [theme,setThemeMode] = useContext(ThemeContext) instead of create and assign state to context use the state from Context

-1
const [themeMode, setThemeMode] = useContext(ThemeContext);

Should be

const [themeMode, setThemeMode] = useState(ThemeContext);
Kien Tran
  • 91
  • 2
  • 8
  • Thanks for your response. It is changing the context on console but not able to pushback changes. In short theme is not changing. – Shrikant Jha Mar 14 '20 at 07:35
  • You should refer here https://reactjs.org/docs/context.html#updating-context-from-a-nested-component. You can refer theme-toggler-button.js, they use toggleTheme method of context instead of useState(ThemeContext) – Kien Tran Mar 14 '20 at 08:35