app-generator / docs

App Generator - The Official Documentation | AppSeed
https://docs.appseed.us
1 stars 1 forks source link

[React] Context API #100

Open mahfujul-helios opened 1 month ago

mahfujul-helios commented 1 month ago

Context API

What is Context API?

The React Context API serves as a means for a React application to efficiently generate global variables that can be seamlessly passed throughout the app. It offers an alternative to the practice of "prop drilling," which involves passing props from one component to its nested children, and so forth. Context is also hailed as a simpler, more lightweight solution compared to using Redux for state management.

Context API, introduced in version 16.3 of React, provides the capability to share state across the entirety of the application or specific parts of it in a lightweight and straightforward manner.

React context API: How it works?

React.createContext() serves as a comprehensive solution, offering both a consumer and a provider. The provider component, as its name implies, furnishes the state to its child components. It acts as the holder of the "store," serving as the parent to all components requiring access to that store. On the other hand, the consumer component is designed to consume and utilize the state provided by the provider, thereby facilitating seamless integration of state management within the React application. More information can be found on React's documentation page

Context API will replace redux?

No. Well, not entirely.

Redux is great and came perfectly to answer the need for state management. Actually, it answered this need so well that it came to be known that you can't be a "true" React developer if you don't know your way around Redux. However, Redux has its disadvantages, and that's why it's important to know what Context API gives us that Redux doesn't:

Simplicity - When using redux people tend to manage almost all of their state in redux and it causes 2 problems:

  1. Overhead - Why should I create/update 3 files just to add one tiny feature?
  2. One of the significant advantages of React's one-way data binding is that it's easy to understand - A component passes state to its children. Using Redux takes it away from us.

Using Context API we can define several unrelated contexts (stores) and use each in its proper place in the app.

Important Note

Redux is just a concept. If you are comfortable with using reducers and actions and don't find hindering than you may also create reducers and actions that wrap Context API as the store as Redux's author Dan Abramov explained in his medium article about whether Redux is always required

How to use Context API?

You might think to yourself: "Well, I'm convinced. How do I implement Context API in my app?" First, make sure you need it. Sometimes people use shared state across nested components instead of just passing it as props. And if you do need it you should follow these very few steps:

  1. Create a folder under your app root named contexts (not required. just a convention)
  2. Create a file named Context.js, e.g. userContext.js
  3. import and create a context like so:
import React, { createContext } from "react";
const UserContext = createContext();

Create a component that will wrap the provider named Provider e.g. UserProvider Example using React Hooks:


const UserProvider = ({ children }) => {
  const [name, setName] = useState("John Doe");
  const [age, setAge] = useState(1);
  const happyBirthday = () => setAge(age + 1);
  return (
    <UserContext.Provider value={{ name, age, happyBirthday }}>
      {children}
    </UserContext.Provider>
  );
};

Create a higher order component to consume the context named: with e.g. withUser Example using React Hooks:

const withUser = (Child) => (props) => (
  <UserContext.Consumer>
    {(context) => <Child {...props} {...context} />}
    {/* Another option is:  {context => <Child {...props} context={context}/>}*/}
  </UserContext.Consumer>
);

The difference between the two options above is if you want the context to be a single nested property by this name, to explode it to its properties (which in my opinion is more convenient).

export { UserProvider, withUser };

And use them however you like For example:

ReactDOM.render(
  <UserProvider>
    <App />
  </UserProvider>,
  document.getElementById("root")
);
export default withUser(LoginForm);