Context-API in react-native

Context-API in react-native

Day-10

App.js

import {Button, StyleSheet, Text, View} from 'react-native';
import React, {useContext} from 'react';
import 'react-native-reanimated';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {PracticeProvider, PracticeContext} from './Global/PracticeContext';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import {AboutStack} from './StackContext';

function HomeScreen() {
  const {val, setVal, val1, setVal1, val2, setVal2} =
    useContext(PracticeContext);
  return (
    <View style={styles.container}>
      <Text style={styles.number}>No.(0)={val}</Text>
      <Text style={styles.number}>No.(1)={val}</Text>
      <Button
        title="Increment"
        onPress={() => {
          setVal(val + 1);
          setVal1(val1 + 1);
        }}
      />
    </View>
  );
}
function DetailScreen() {
  const {val, setVal, val1, setVal1, val2, setVal2} =
    useContext(PracticeContext);
  return (
    <View style={{flex: 1, justifyContent: 'center'}}>
      <View style={styles.container}>
        <Text style={styles.number}>No.(1)={val}</Text>
        <Text style={styles.number}>No.(2)={val}</Text>
      </View>
      <View>
        <Button
          title="Decrement"
          onPress={() => {
            setVal(val - 1);
            setVal1(val1 - 1);
          }}
        />
      </View>
    </View>
  );
}

const Tab = createBottomTabNavigator();
export default function App() {
  return (
    <PracticeProvider>
      <NavigationContainer>
        <Tab.Navigator
          screenOptions={{
            tabBarActiveTintColor: 'red',
            tabBarInactiveTintColor: 'gray',
            tabBarLabelStyle: {
              fontSize: 20,
              fontWeight: 'bold',
            },
          }}>
          <Tab.Screen
            name="StackINC"
            component={AboutStack}
            options={{
              headerStyle: {backgroundColor: 'yellow'},
              headerTintColor: 'black',
              headerTitleStyle: {
                fontWeight: 'bold',
                fontSize: 30,
              },
              headerTitleAlign: 'center',
              tabBarIcon: ({color}) => (
                <MaterialIcons name="text-increase" color={color} size={22} />
              ),
              tabBarColor: 'red',
              headerShown: false,
            }}
          />
          <Tab.Screen
            name="Decrement"
            component={DetailScreen}
            options={{
              headerStyle: {backgroundColor: 'yellow'},
              headerTintColor: 'black',
              headerTitleStyle: {
                fontWeight: 'bold',
                fontSize: 30,
              },
              headerTitleAlign: 'center',
              tabBarIcon: ({color}) => (
                <MaterialIcons name="text-decrease" color={color} size={22} />
              ),
            }}
          />
        </Tab.Navigator>
      </NavigationContainer>
    </PracticeProvider>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-evenly',
  },
  number: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'black',
    padding: 10,
  },
});

This React Native app utilizes the context API to manage and share global state across different components and employs a bottom tab navigator for navigation between screens. Here’s a breakdown of the main components and functionality:

  1. Context Setup:

    • PracticeContext: A React context created to manage and share state (val, val1, val2, and their corresponding setters) across different components in the app.

    • PracticeProvider: A context provider that wraps the main component of the app, making the state available to all nested components.

  2. Screens:

    • HomeScreen: Displays two text components that reflect the value of val from the context. It includes a button to increment both val and val1.

    • DetailScreen: Similar to HomeScreen, it displays the context values but provides a button to decrement val and val1.

  3. Navigation:

    • Tab Navigator: Utilizes createBottomTabNavigator from @react-navigation/bottom-tabs to allow switching between an AboutStack (not detailed in the snippet but presumably a stack navigator for additional screens) and the DetailScreen.

    • Each tab screen is configured with icons and custom styling to improve the user interface, like active/inactive color changes and custom font sizes for the tab labels.

  4. Styling:

    • Uses StyleSheet for defining styles such as layout (flex-direction, alignment) and text appearance (font size, weight).
  5. App Component:

    • The main function component App wraps the navigation and screens within the PracticeProvider, ensuring that the state managed by the context is accessible throughout the component hierarchy inside the navigator.

This structure allows for state management across different levels of the application while providing a navigational structure that enhances the user experience with visual feedback and easy navigation controls.

StackContext.js for making stack and combine it with the tab

import {
  View,
  Text,
  SafeAreaView,
  ScrollView,
  StatusBar,
  Button,
  StyleSheet,
  TouchableOpacity,
} from 'react-native';
import React, {useContext} from 'react';
import {NavigationContainer, useNavigation} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {PracticeProvider, PracticeContext} from './Global/PracticeContext';
const Stack = createNativeStackNavigator();

function HomeScreen() {
  const navigation = useNavigation();
  const {val, setVal, val1, setVal1} = useContext(PracticeContext);
  return (
    <View style={{flex: 1, justifyContent: 'center'}}>
      <View style={styles.container}>
        <Text style={styles.number}>No.(1)={val}</Text>
        <Text style={styles.number}>No.(2)={val}</Text>
      </View>
      <View>
        <Button
          title="Increment"
          onPress={() => {
            setVal(val + 1);
            setVal1(val1 + 1);
          }}
        />
        <TouchableOpacity
          style={styles.button}
          onPress={() => navigation.navigate('Decrement')}>
          <Text style={styles.buttonText}>Decrement Screen</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

function AnotherScreen() {
  const navigation = useNavigation();
  return (
    <View style={styles.container1}>
      <Text style={styles.textheader}>Click on Increment Page</Text>
      <Button
        title="Increment Page"
        onPress={() => navigation.navigate('Home')}
      />
    </View>
  );
}

function GotoScreen() {
  return (
    <View style={styles.container}>
      <Text style={styles.textheader}>Goto Decrement TabBar</Text>
    </View>
  );
}
export const AboutStack = () => {
  return (
    <Stack.Navigator
      screenOptions={{
        tabBarActiveTintColor: 'red',
        tabBarInactiveTintColor: 'gray',
        tabBarLabelStyle: {
          fontSize: 20,
          fontWeight: 'bold',
        },
      }}>
      <Stack.Screen
        name="Another"
        component={AnotherScreen}
        options={{
          headerStyle: {backgroundColor: 'yellow'},
          headerTintColor: 'black',
          headerTitleStyle: {
            fontWeight: 'bold',
            fontSize: 30,
          },
          headerTitleAlign: 'center',
          headerTitle: 'Increment Stack',
        }}
      />
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          headerStyle: {backgroundColor: 'yellow'},
          headerTintColor: 'black',
          headerTitleStyle: {
            fontWeight: 'bold',
            fontSize: 30,
          },
          headerTitleAlign: 'center',
          headerTitle: 'Increment Page',
        }}
      />
      <Stack.Screen
        name="Decrement"
        component={GotoScreen}
        options={{
          headerStyle: {backgroundColor: 'yellow'},
          headerTintColor: 'black',
          headerTitleStyle: {
            fontWeight: 'bold',
            fontSize: 30,
          },
          headerTitleAlign: 'center',
        }}
      />
    </Stack.Navigator>
  );
};

const AppStack = () => {
  return (
    <NavigationContainer>
      <AboutStack />
    </NavigationContainer>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  number: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'black',
    padding: 10,
  },
  textheader: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'black',
    padding: 10,
    textAlign: 'center',
  },
  button: {
    backgroundColor: '#007BFF', // Blue background color for the button
    paddingHorizontal: 20, // Horizontal padding
    paddingVertical: 10, // Vertical padding
    borderRadius: 2, // Rounded corners
    marginTop: 10, // Margin
  },
  buttonText: {
    color: '#ffffff', // White text color
    fontSize: 16, // Font size
    textAlign: 'center',
  },
  container1: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default AppStack;

PracticeContext.js compiling the context api

import React from 'react';
const PracticeContext = React.createContext();

const PracticeProvider = ({children}) => {
  const [val, setVal] = React.useState(0);
  const [val1, setVal1] = React.useState(1);
  const [val2, setVal2] = React.useState(2);
  const [val3, setVal3] = React.useState(3);
  const [val4, setVal4] = React.useState(4);
  return (
    <PracticeContext.Provider
      value={{
        val,
        setVal,
        val1,
        setVal1,
        val2,
        setVal2,
        val3,
        setVal3,
        val4,
        setVal4,
      }}>
      {children}
    </PracticeContext.Provider>
  );
};

export {PracticeContext, PracticeProvider};

Increment Stack

Decrement tab