What’s the right solution for React state management?
State management is the backbone of every React application, impacting its performance, scalability, and maintainability. It helps you efficiently maintain and share data across components. However, as applications grow, managing state can become challenging, leading to issues like prop drilling, redundant state updates, and performance bottlenecks. Choosing the right solution can make the difference between a smooth user experience and a buggy, unresponsive app.
But fear not! In this blog, we'll have a look at the React context API and some of the most used external stores, exploring their strengths, weaknesses, and best use cases. By the end, you'll know exactly when to use each one — or even both together.
At the end of this blog, you'll find a detailed example provided by our awesome colleague Jovan, to help you better understand these concepts! ??
State management options in React
React provides several ways to manage state:
Local state
The simplest form of state management in React is using component state, often referred to as local state. This is managed within a single component using the useState hook. It’s perfect for handling data that doesn’t need to be shared across components, like form inputs or simple counters.
React context API
React context is a built-in React tool that allows you to create a context object and a provider component that can pass state down through the component tree without needing to pass props manually at every level. This approach is great for themes, user authentication, and other global settings.
React context consists of 3 main parts:
While React context provides a convenient way to share data, it comes with some performance considerations – every time the value provided by the Provider changes, all components consuming that context will re-render. This can lead to performance issues, especially if the context is large or globally wraps the app with updating data frequently.
Pros:
Cons:
External stores
External stores are third-party libraries designed to manage state outside of the React component tree. These libraries provide a more structured and scalable approach to state management and they’re highly beneficial in managing state for large and complex React applications.?
They’re particularly useful in scenarios where you need to share state across different parts of your application without causing unnecessary re-renders. You can subscribe to specific parts of the state, improving performance by updating only the components that need to be re-rendered.?
Here are some popular React external stores:
领英推荐
Pros:
Cons:
Can we make our own external store without third-party packages? ??
Yes, we can! Starting from version 18, React provides the useSyncExternalStore API which allows us to subscribe to a state defined outside of React and write our own implementation of an external store. This means we don't necessarily need third-party packages to manage external state!
So, what’s the best choice to make?
One of the main disadvantages of external stores is the inability to encapsulate data.? However, there's a solution that combines the performance benefits of external stores with the encapsulation provided by React context. By using regular context, you can subscribe to specific parts of the state and avoid unnecessary re-renders of other components.
To achieve this, initialize the external store within the Provider component, ideally using the useState hook for the default state value, and pass that state to the Provider. This approach ensures the state of the external store is set once during the rendering of the Provider component. By maintaining a consistent state value without changing it through setState, you prevent re-renders of all components subscribed to that context.
This way, the encapsulation of data stored in the external store is enabled while retaining the advantages of preventing re-renders of components where the part of the state has not changed. So, by combining external stores with React context, you can achieve the best of both worlds ?
Practical example
Want to see these concepts in action? Check out the example application prepared by our colleague Jovan on StackBlitz ??
In the example, an external store is defined in the index file and instantiated using the createStore function, which internally uses the useSyncExternalStore hook.?
While we don't need to detail the implementation here, it's important to note that creating a custom external store without packages is indeed possible.
Open the console and track component re-renders as the state changes in all three modes to fully understand their behaviour!
With the right state management strategy, you'll be well-prepared to overcome the challenges of building dynamic and responsive React applications.?
What state management solution do you prefer for your React projects? Leave a comment below to share your experiences. For more insights and detailed articles, explore our blog section at Ncoded Solutions.
Happy coding and may your apps always run smoothly! ??