React Context - Sharing Data b/w Components without a drill-down

React Context - Sharing Data b/w Components without a drill-down

Context in React is a way to share data between components without having to pass it down through every level of the component tree. This can make your code more efficient and less error-prone, especially when dealing with large applications, with the help of typescript you can catch errors and improve the reliability of your code. Here's how to use context in React with TypeScript.


Step 1: Create a new context

First, let's create a new context using React.createContext. We'll define an interface for our user object, which will include a username, email, and password.

import React from "react";

export interface User {
? username: string;
? email: string;
? password: string;
}

export interface UserContextType {
? user: User | null;
? registerUser: (user: User) => void;
}

export const UserContext = React.createContext<UserContextType>({
? user: null,
? registerUser: (user: User) => {},
});        

In this example, we've defined a UserContextType interface that includes a user object of type User and a registerUser function that takes a User object as its argument.

We've also set up a default value for the context that includes a user object set to null and a registerUser function that does nothing.


Step 2: Create a provider component

Next, let's create a provider component that will set the context value using useState. We'll define our UserProvider component to include a user state variable and a registerUser function.

import React, { useState } from "react";
import {UserContext, User, UserContextType } from "./UserContext";

interface UserProviderProps {
? children: React.ReactNode;
}

const UserProvider: React.FC<UserProviderProps> = ({ children }) => {
? const [user, setUser] = useState<User | null>(null);

? const registerUser = (newUser: User) => {
? ? setUser(newUser);
? };

? const contextValue: UserContextType = {
? ? user,
? ? registerUser,
? };

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

export default UserProvider;        

Here, we've defined the UserProvider component with a children prop that represents the child components that will consume the context.

We've also defined the user state variable using useState and a registerUser function that sets the user state variable to the new user object.

Finally, we've created a contextValue object that includes the user and registerUser properties and set it as the value for the UserContext.Provider component.


Step 3: Create a consumer component

Next, let's create a consumer component that will consume the context using the useContext hook. We'll define a UserInfo component that will display the user's information if a user is logged in.

import React, { useContext } from "react";
import {UserContext} from "./UserContext";

const UserInfo: React.FC = () => {
? const { user } = useContext(UserContext);

? if (user) {
? ? return (
? ? ? <div>
? ? ? ? <h1>User Info</h1>
? ? ? ? <p>Username: {user.username}</p>
? ? ? ? <p>Email: {user.email}</p>
? ? ? </div>
? ? );
? }

? return null;
};

export default UserInfo;        

Here, we've used the useContext hook to consume the UserContext. We've destructured the user object from the context and returned a div that displays the user's information if a user is logged in. If no user is logged in, we return null.


Step 4: Create a form component

We'll define a RegistrationForm component that will render a form for users to register. When the form is submitted, we'll call the registerUser function from the context to update the user state.

import React, { useContext, useState } from "react";
import { UserContext,User } from "./UserContext";

const RegistrationForm: React.FC = () => {
? const { registerUser } = useContext(UserContext);

? const [username, setUsername] = useState("");
? const [email, setEmail] = useState("");
? const [password, setPassword] = useState("");

? const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
? ? event.preventDefault();

? ? const newUser: User = {
? ? ? username,
? ? ? email,
? ? ? password,
? ? };

? ? registerUser(newUser);

? ? setUsername("");
? ? setEmail("");
? ? setPassword("");
? };

? return (
? ? <form onSubmit={handleSubmit}>
? ? ? <label>
? ? ? ? Username:
? ? ? ? <input
? ? ? ? ? type="text"
? ? ? ? ? value={username}
? ? ? ? ? onChange={(event) => setUsername(event.target.value)}
? ? ? ? />
? ? ? </label>
? ? ? <label>
? ? ? ? Email:
? ? ? ? <input
? ? ? ? ? type="email"
? ? ? ? ? value={email}
? ? ? ? ? onChange={(event) => setEmail(event.target.value)}
? ? ? ? />
? ? ? </label>
? ? ? <label>
? ? ? ? Password:
? ? ? ? <input
? ? ? ? ? type="password"
? ? ? ? ? value={password}
? ? ? ? ? onChange={(event) => setPassword(event.target.value)}
? ? ? ? />
? ? ? </label>
? ? ? <button type="submit">Register</button>
? ? </form>
? );
};

export default RegistrationForm;        

In this example, we've used useState to define state variables for the username, email, and password inputs. We've also destructured the registerUser function from the UserContext.

When the form is submitted, we create a new User object using the values from the form inputs and call the registerUser function from the context to update the user state. Finally, we reset the input fields by calling setUsername, setEmail, and setPassword with empty strings.


Step 5: Use the provider component

Now that we've defined our context, provider, consumer, and form components, we can use the UserProvider component to wrap our application and provide the UserContext to our child components.

import React from "react";
import UserProvider from "./UserProvider";
import RegistrationForm from "./Form";
import UserInfo from "./Consumer";

const App: React.FC = () => {
? return (
? ? <UserProvider>
? ? ? <RegistrationForm />
? ? ? <UserInfo />
? ? </UserProvider>
? );
};

export default App;        

Here, we've imported and used the UserProvider component to wrap our RegistrationForm and UserInfo components. This will provide the UserContext to these components and allow them to consume and update the user state.

That's it! we have successfully setup context in a React TypeScript application. You can use this pattern to manage other shared state in your application as well.

Happy coding...

Hello Taimoor... I would like to invite you for interview at HulkHire. If you crack the interview, We will share your profile with hundreds of HRs and help you get your dream job. You can apply for the interview on this link - https://talent.hulkhire.com/#/schedule/hulkhire/software%20engineer/183/1 If you dont, No worries.. We will let you know area of improvement. If you know any of your friends, who you think have great potential and would great resource for IT companies, feel free to share it with them as well. More details are available on this link- https://jobs.hulkhire.com/faqs If you have any questions please reach out to me on Whatsapp - 8886080289 Happy to answer your queries.

回复

要查看或添加评论,请登录

Taimoor Khan Kasi的更多文章

社区洞察

其他会员也浏览了