Search code examples
reactjsreact-nativereact-hooksreact-context

React native useContext returns undefined


I can't access the data passed by createContext using useContext hook in the functional component in react native : context.js is as

import React , {createContext,useState}  from 'react';
 export const Style1 = React.createContext();
export  default StyleContextProvider = (props) => {
const [myValue,setValue] = useState([{one: 1},{two : 2}]);
console.log("value from context : " + myValue);
    return ( 
        <Style1.Provider value={[myValue,setValue]}>
          {props.children}
        </Style1.Provider>
     );
}

and App.js is as

import React from 'react';
import Sidebar from './routes/sidebar';
import StyleContextProvider from './routes/context';
export default function App(props) {
  return (
        <StyleContextProvider>
          <Sidebar ></Sidebar>
        </StyleContextProvider>
  );
}

Sidebar.js is as

import React ,{useContext } from 'react';
import {  Text, View ,Button} from 'react-native';
import Style1 from '../routes/context';
const Sidebar = () =>{
 const value =  useContext(Style1);
 console.log("value from sidebar : " + value);  // value from sidebar : undefined

return (
    <View>
      <Practice></Practice>
    </View>
)
}

Practice.js

import  React  ,{useContext }from 'react';
import { Button } from 'react-native-elements';
import {View, StyleSheet,Text} from 'react-native';
import Style1 from '../routes/context';
const Practice = (props) => {
  const  Value =  useContext(Style1);
  console.log("value from practice : " + Value); // value from practice : undefined 
    return ( 
      <View >
        <Text>Value : {Value}</Text>
      </View>
     );
}
 export default Practice;

I'm getting undefined from the practice .js and sidebar.js , Any one with solution


Solution

  • From your context you are setting the values as value={[myValue,setValue]}.

    Which means in order to access them, you'll need to use Destructuring assignment like:

    const [value, setValue] = React.useContext(Style1);
    

    Another note, since value is an array of objects, you cannot directly render it. You'll either need to iterate using map() or access the value directly.

    - <Text>Value : {Value}</Text>
    + <Text>Value : {value[0].one}</Text>
    

    Here is a working sample based off of your snippets:

    const Style1 = React.createContext();
    const StyleContextProvider = (props) => {
      const [myValue, setValue] = React.useState([{ one: 1 }, { two: 2 }]);
      console.log("value from context : ", myValue);
      return (
        <Style1.Provider value={[myValue, setValue]}>
          {props.children}
        </Style1.Provider>
      );
    };
    
    const View = (props) => <div>{props.children}</div>;
    const Text = (props) => <span>{props.children}</span>;
    
    const Practice = (props) => {
      const [value] = React.useContext(Style1);
      console.log("value from practice : ", value); // value from practice : undefined
      return (
        <View>
          <Text>Value : {value[0].one}</Text>
        </View>
      );
    };
    
    const Sidebar = () => {
      const [value] = React.useContext(Style1);
      console.log("value from sidebar : ", value); // value from sidebar : undefined
    
      return (
        <View>
          <Practice></Practice>
        </View>
      );
    };
    
    function App(props) {
      return (
        <StyleContextProvider>
          <Sidebar></Sidebar>
        </StyleContextProvider>
      );
    }
    
    
    ReactDOM.render(<App />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>

    P.S: I do not know how to render React Native stuff using the StackOverflow snippet widget, hence took the liberty to create Text and View components.