Which is Better React State Management Libraries?
use-context-selector vs constate

1 Year
use-context-selectorconstate
What's React State Management Libraries?

React state management libraries provide tools and patterns for managing state in React applications. They help organize and update application data in a predictable and efficient way. Choosing the right library depends on the project's complexity, scalability needs, and developer preferences.

NPM Package Downloads Trend
Github Stars Ranking
Stat Detail
Package
Weekly Downloads
Github Stars
Issues
Commit
License
use-context-selector261,6972,47723 days agoMIT License
constate134,7293,91692 years agoMIT License
Feature Comparison: use-context-selector vs constate

State Management

  • constate: Constate is a simple and flexible state management library that leverages React's context API. It allows for the creation of custom hooks to manage and share state logic across components.
  • use-context-selector: Use-context-selector is a lightweight library that simplifies state management by providing a selector function to access specific context values. It helps reduce boilerplate code and improves performance by optimizing context updates.

Performance Optimization

  • constate: Constate optimizes performance by memoizing state values and only re-rendering components when necessary. It helps prevent unnecessary renders and improves the overall application performance.
  • use-context-selector: Use-context-selector enhances performance by allowing components to subscribe to specific context values. This selective subscription reduces re-renders and improves the efficiency of state updates.

Flexibility

  • constate: Constate offers flexibility in state management by allowing developers to create custom hooks with specific logic and dependencies. It provides a more granular control over state updates and sharing.
  • use-context-selector: Use-context-selector provides flexibility in accessing context values with a selector function. Developers can choose which values to subscribe to, enabling more targeted state management.

Ease of Use

  • constate: Constate is easy to use and integrates seamlessly with React components. It follows a simple API design that makes state management straightforward and intuitive for developers.
  • use-context-selector: Use-context-selector simplifies state management by offering a concise and clear way to access context values. It reduces the complexity of context usage and improves the overall developer experience.

Scalability

  • constate: Constate supports scalability by enabling the creation of reusable state logic that can be shared across multiple components. It helps maintain a consistent state management approach as the application grows.
  • use-context-selector: Use-context-selector aids in scalability by providing a structured way to access context values based on specific requirements. It facilitates the management of complex state structures in larger applications.
README for use-context-selector

use-context-selector

CI npm size discord

React useContextSelector hook in userland

Introduction

React Context and useContext is often used to avoid prop drilling, however it's known that there's a performance issue. When a context value is changed, all components that useContext will re-render.

To solve this issue, useContextSelector is proposed and later proposed Speculative Mode with context selector support. This library provides the API in userland.

Prior to v1.3, it uses changedBits=0 feature to stop propagation, v1.3 no longer depends on this undocumented feature.

Install

This package requires some peer dependencies, which you need to install by yourself.

yarn add use-context-selector react scheduler

Notes for library authors:

Please do not forget to keep "peerDependencies" and note instructions to let users to install peer dependencies.

Technical memo

To make it work like original React context, it uses useReducer cheat mode intentionally.

It also requires useContextUpdate to behave better in concurrent rendering. Its usage is optional and only required if the default behavior is unexpected.

Usage

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

import { createContext, useContextSelector } from 'use-context-selector';

const context = createContext(null);

const Counter1 = () => {
  const count1 = useContextSelector(context, v => v[0].count1);
  const setState = useContextSelector(context, v => v[1]);
  const increment = () => setState(s => ({
    ...s,
    count1: s.count1 + 1,
  }));
  return (
    <div>
      <span>Count1: {count1}</span>
      <button type="button" onClick={increment}>+1</button>
      {Math.random()}
    </div>
  );
};

const Counter2 = () => {
  const count2 = useContextSelector(context, v => v[0].count2);
  const setState = useContextSelector(context, v => v[1]);
  const increment = () => setState(s => ({
    ...s,
    count2: s.count2 + 1,
  }));
  return (
    <div>
      <span>Count2: {count2}</span>
      <button type="button" onClick={increment}>+1</button>
      {Math.random()}
    </div>
  );
};

const StateProvider = ({ children }) => (
  <context.Provider value={useState({ count1: 0, count2: 0 })}>
    {children}
  </context.Provider>
);

const App = () => (
  <StateProvider>
    <Counter1 />
    <Counter2 />
  </StateProvider>
);

ReactDOM.render(<App />, document.getElementById('app'));

API

createContext

This creates a special context for useContextSelector.

Parameters

  • defaultValue Value

Examples

import { createContext } from 'use-context-selector';

const PersonContext = createContext({ firstName: '', familyName: '' });

useContextSelector

This hook returns context selected value by selector.

It will only accept context created by createContext. It will trigger re-render if only the selected value is referentially changed.

The selector should return referentially equal result for same input for better performance.

Parameters

  • context Context<Value>
  • selector function (value: Value): Selected

Examples

import { useContextSelector } from 'use-context-selector';

const firstName = useContextSelector(PersonContext, state => state.firstName);

useContext

This hook returns the entire context value. Use this instead of React.useContext for consistent behavior.

Parameters

  • context Context<Value>

Examples

import { useContext } from 'use-context-selector';

const person = useContext(PersonContext);

useContextUpdate

This hook returns an update function that accepts a thunk function

Use this for a function that will change a value in concurrent rendering in React 18. Otherwise, there's no need to use this hook.

Parameters

  • context Context<Value>

Examples

import { useContextUpdate } from 'use-context-selector';

const update = useContextUpdate();

// Wrap set state function
update(() => setState(...));

// Experimental suspense mode
update(() => setState(...), { suspense: true });

BridgeProvider

This is a Provider component for bridging multiple react roots

Parameters

  • $0 {context: Context<any>, value: any, children: ReactNode}

    • $0.context
    • $0.value
    • $0.children

Examples

const valueToBridge = useBridgeValue(PersonContext);
return (
  <Renderer>
    <BridgeProvider context={PersonContext} value={valueToBridge}>
      {children}
    </BridgeProvider>
  </Renderer>
);

useBridgeValue

This hook return a value for BridgeProvider

Parameters

  • context Context<any>

Limitations

  • In order to stop propagation, children of a context provider has to be either created outside of the provider or memoized with React.memo.
  • Provider trigger re-renders only if the context value is referentially changed.
  • Neither context consumers or class components are supported.
  • The stale props issue can't be solved in userland.
  • Tearing is only avoided if all consumers get data using useContextSelector. If you use both props and use-context-selector to pass the same data, they may provide inconsistence data for a brief moment. (02_tearing_spec fails)

Examples

The examples folder contains working examples. You can run one of them with

PORT=8080 yarn run examples:01_minimal

and open http://localhost:8080 in your web browser.

You can also try them in codesandbox.io: 01 02 03

Projects that use use-context-selector