React useSelectorContext hook, support custom isEqual function
npm install use-selector-context


React useSelectorContext hook, support custom isEqual function.
This hook only depends on React and doesn't require any other external library. This makes it a lightweight and efficient option for managing and using state in your React applications.
React Context and the useContext hook are frequently employed as solutions to circumvent prop drilling. However, it's widely recognized that this approach comes with a performance drawback. Specifically, every time the value of a context changes, all components utilizing the useContext hook will be triggered to re-render.
To solve this issue,
useSelectorContext
is proposed and later proposed.
The useSelectorContext supports custom selector and isEqual functions, providing fine-grained control over the conditions that trigger a re-render.
This package requires react >= 18.
``bash`
npm install use-selector-contextor
yarn add use-selector-contextor
pnpm add use-selector-context
To make it work like original React context, it uses
useSyncExternalStore without any libraries.
Inspiration was drawn from an example.
`javascript
import React, { memo, useMemo, useState, createRoot } from 'react';
import { useContext, createContext, shallowEqual } from 'use-selector-context';
const context = createContext<{
v1: number;
v2: number;
v3: number[];
setV1?: React.Dispatch
setV2?: React.Dispatch
setV3?: React.Dispatch
}>({
v1: 0,
v2: 0,
v3: [],
});
const Child1 = memo(() => {
const v1 = useContext(context, (v) => v.v1);
const setV1 = useContext(context, (v) => v.setV1);
return (
const Child2 = memo(() => {
const { v2, setV2 } = useContext(context, (v) => ({ v2: v.v2, setV2: v.setV2 }), shallowEqual);
return
});
const Child22 = memo((props: any) => {
return (
const Child3 = memo(() => {
const { v3, setV3 } = useContext(context);
return (
const useAppContext = useContext.withContext(context);
const Child4 = memo(() => {
const { v3 } = useAppContext((v) => ({ v3: v.v3 }), shallowEqual);
return
const Child5 = memo(() => {
const { v3 } = useAppContext();
return
function App() {
const [v1, setV1] = useState(0);
const [v2, setV2] = useState(0);
const [v3, setV3] = useState
const contextValue = useMemo(() => {
return { v1, v3, setV1, setV3, v2, setV2 };
}, [v1, v2, v3]);
return ( render My context app ⬇️ WIP
);
}
createRoot(document.getElementById('app')).render(
`
This creates a special context for useSelectorContext.
#### Parameters
- defaultValue Value
#### Examples
`javascript
import { createContext } from 'use-selector-context';
const AppContext = createContext({ a: '', b: '' });
`
This hook returns context selected value by selector.
useContext only accepts contexts created by createContext. It initiates a re-render only when the selected value undergoes a referential change.
- By default, selector uses the function (value) => value to retrieve the value. You have the option to use destructuring to extract data.isEqual
- By default, uses Object.is for comparison. However, you have the flexibility to use shallowEqual(import ) or your own custom isEqual function to determine when the selected value has changed.
#### Parameters
- context ZContext\selector?
- function (value: Value): Selected isEqual?
- function (a: Selected,b: Selected): boolean
#### Examples
`javascript
import { useContext, shallowEqual } from 'use-selector-context';
const a = useContext(AppContext, (state) => state.a);
// or
const b = useContext(AppContext, (state) => {
b: state.a;
});
// or
const c = useContext(
AppContext,
(state) => {
c: state.a;
},
shallowEqual
);
`
Similar to React Redux useSelector, you can use useContext.withContext to specify the context type and to pass in the default parameters for the context.
#### Parameters
- context ZContext\
#### Examples
`javascript
import { useContext, shallowEqual } from 'use-selector-context';
const useAppContext = useContext.withContext(AppContext);
// or
const a = useAppContext((state) => {
b: state.a;
});
// or
const c = useAppContext((state) => {
c: state.a;
}, shallowEqual);
`
It is used to get the current snapshot of the provided context.
#### Parameters
- defaultValue ZContext
#### Examples
`javascript`
import { useGetSnapshot } from 'use-selector-context';
// in Component
const getAppContext = useGetSnapshot(AppContext);
You can use useGetSnapshot.withContext to specify the context type and to pass in the default parameters for the context.
#### Parameters
- defaultValue ZContext
#### Examples
`javascript
import { useGetSnapshot } from 'use-selector-context';
const useGetAppSnapshot = useGetSnapshot.withContext(context);
// in Component
const getAppContext = useGetAppSnapshot();
`
The example folder contains working examples.
You can run one of them with
`bash``
pnpm run example
and open
You can also try them directly:
Online Example