Home > Enterprise >  Context not working properly in React-Native
Context not working properly in React-Native

Time:10-26

Here is my Context File:

import React from 'react';
import { createContext, useState } from 'react';

export const TabContext = createContext({
    opened: false,
    toggleOpened: () => {},
});

export const TabContextProvider = ({ children }) => {
    const [opened, setOpened] = useState(false);

    const toggleOpened = () => {
        setOpened(!opened);
    };

    return (
        <TabContext.Provider value={{ opened, toggleOpened }}>
            {children}
        </TabContext.Provider>
    );
};

My Simplified App.js File: (Necessary files are imported)

const Tab = createBottomTabNavigator();

export default function App() {
    const buttonCtx = useContext(TabContext);

    return (
        <>
            <TabContextProvider>
                <NavigationContainer>
                    <Tab.Navigator>
                        <Tab.Screen
                            name='Action'
                            component={ActionScreen}
                            options={{
                                tabBarButton: () => (
                                    <ActionButton
                                        opened={buttonCtx.opened}
                                        toggleOpened={buttonCtx.toggleOpened}
                                    />
                                ),
                            }}
                        />
                    </Tab.Navigator>
                </NavigationContainer>
            </TabContextProvider>
        </>
    );
}

And the Simplified ActionButton Component:

export default function ActionButton({ opened, toggleOpened }) {
    return (
        <View style={styles.container}>
            <View style={styles.box}>
                <TouchableWithoutFeedback
                    onPress={toggleOpened}
                    style={styles.actionButton}
                >
                    /* With an Animated View inside */
                </TouchableWithoutFeedback>
            </View>
        </View>
    );
}

Basically, **toggleOpened **should switch the value of the variable **opened **between true and false. So the **AnimatedView **can work properly which solely depends on the value of opened.

Opened is readable in all of the components, no problem with that. But **toggleOpened **is not working at all. Any idea?

CodePudding user response:

In order to use contexts properly, you need to have at least two components working together,one that renders the Provider and one descendant who then uses that context.

You are trying to provide and use the context at the same time,try to move the consumer component one position down to the hierarchy.

For example in your App.js you can create a consumer component to wrap your ActionButton,then pass the context to it as you did :

export default function App() {
  return (
    <>
      <TabContextProvider>
        <NavigationContainer>
          <Tab.Navigator>
            <Tab.Screen
              name="Action"
              component={ActionScreen}
              options={{
                tabBarButton: () => <ActionButtonWrapper />
              }}
            />
          </Tab.Navigator>
        </NavigationContainer>
      </TabContextProvider>
    </>
  );
}

const ActionButtonWrapper = () => {
  const { opened, toggleOpened } = useContext(TabContext);
  return (
    <>
      <ActionButton
        opened={opened}
        toggleOpened={toggleOpened}
      />
    </>
  );
};

However,i would just use the context directly within ActionButton,after all,passing props down to children is what we want to avoid by using context,right?

I have created for you a snippet to see how we can properly use context

  • Related