paint-brush
Creating Context in ReactJS Using TypeScriptby@radunemerenco
11,040 reads
11,040 reads

Creating Context in ReactJS Using TypeScript

by Radu NemerencoJuly 1st, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

ContextAPI is one of the most exciting features of ReactJS that helps us implement the state management in our React apps without importing extra libraries, like Redux or MobX. For this specific example I’ll use some basic functionalities without complex logic.
featured image - Creating Context in ReactJS Using TypeScript
Radu Nemerenco HackerNoon profile picture

ContextAPI is one of the most exciting features of ReactJS which was released in early 2019 that helps us implement the state management in our React apps without importing extra libraries, like Redux or MobX.

First of All, We’ll Define Some Types.

UserData type is not so important for this tutorial, and that’s why we’ll define some key properties which might be different based on your specific needs:


type UserData = {
  userId: string;
  name: string;
  nickName: string
  email: string;
}


Then we need to think about what we need your context to do. For this specific example I’ll use some basic functionalities without complex logic.


interface ContextProps {
  readonly userData: UserData | null;
  readonly setUserData: (userData: UserData) => void;
  readonly loadUserData: () => Promise<void>;
}


  • userData — this will be a react state value representing the current user data.
  • setUserData(userData) — this is the state modifier for userData, in case of some properties update of the user, to be able to update it’s properties.
  • loadUserData() — in case we need to reload the user data from outside of the Context.

Creating the Context

const UserContext = React.createContext<ContextProps>({
  userData: null,
  setUserData: () => null,
  loadUserData: async () => {},
});


The only thing you really need to to in order to create a context is to use React.createContext(). In our case we’re giving a type to the context, which is ContextProps and a default value as an argument.


Some devs prefer to define the context without initial value, but that way you might have to check if userContext.loadUserDate is defined before calling the function.

Let’s Write Some Logic

const UserProvider: React.FC = ({ children }) => {
  const [userData, setUserData]
    = React.useState<UserData | null>(null);

  const loadUserData = async () => {
    console.log('load')
  };

  const value = {
    userData,
    setUserData,
    loadUserData,
  };

  return (
    <UserContext.Provider value={value}>
      {children}
    </UserContext.Provider>
  );
};


The most important part from this file related to ContextAPI as a functionality is the return statement. This is the actual context provider (UserContext.Provider) that will create the “scope” for this context and make it available in all of it’s children at any level.


Let’s say, we want our context to load automatically the user data without needing to call the userContext.loadUserData() from some of the children. In order to achieve this, we’ll write an useEffect that will make our initial load.


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


And now let’s update our loadUserData function and implement a sample API call to a non existing API, for the sake of example.


const loadUserData = async () => {
  try {
    const response: UserData | null = await fetch('https://my-website/api/user');
    await response.json();

    if (response) {
      setUserData(response);
    }
  } catch (err) {
    console.log(err);
  }
};


And now we’re all set. Now let’s see how to access our context.

How to Access The Context in Your React App


First of all, in order to have access to a context from a component, this component needs to be a child (at any level) of the Context.Provider. So, to demonstrate this we’ll create 2 components:


App.tsx

export default function App() {
  return (
      <UserProvider>
        <UserInfo />
      </UserProvider>
  );
}


UserInfo.tsx

const UserInfo: React.FC = () => {
  const { userData } = React.useContext(UserContext);
  if (!userData) return null;

  return (
      <div>
        <p>{userData.userId}</p>
        <p>{userData.name}</p>
        <p>{userData.nickName}</p>
        <p>{userData.email}</p>
      </div>
  );
};

export default UserInfo;


If you need to use the context in a class component you’ll have to use contextType static property


class UserInfo extends React.Component {
  static contextType = UserContext;

  render() {
    const { userData } = this.context;

    if (!userData) return null;

    return (
        <div>
          <p>{userData.userId}</p>
          <p>{userData.name}</p>
          <p>{userData.nickName}</p>
          <p>{userData.email}</p>
        </div>
    );
  }
}

export default UserInfo;


In conclusion, React’s Context API is a handy tool that helps to create global (and not only) states without using Redux or other similar libraries.


Also published here.