A new way to use “useContext” better
npm install use-global-context
Use-global-context is a new way to use useContext better with selector.
useSelector function.context API allows you to create a simple store.However, it can lead to unnecessary renders if you don't split the context with proper granularity. It also doesn't have a feature like redux's useSelector. That means you have to memo. Please see the basic solutions.
This library is intended to prevent unnecessary renders with selector, which is a problem with the context API and easily manage global state.
npm install use-global-context
`or
`
yarn add use-global-context
`
Usage
$3
The first step is to define the reducer and its state.`javascript
export const incrementCount = () => ({ type: "INCREMENT" });
export const decrementCount = () => ({ type: "DECREMENT" });export const counterReducer = (state, action) => {
switch (action.type) {
case "INCREMENT": {
return {
count: state.count + 1
};
}
case "DECREMENT": {
return {
count: state.count - 1
};
}
default: {
return state;
}
}
};
export const initialCounterState = {
count: 100,
error: null,
status: null,
};
`Next, you can use it in the use-global-context API as follows.
`javascript
import { createGlobalContext } from "use-global-context";
import {
incrementCount,
decrementCount,
counterReducer,
initialCounterState,
} from "./reducer/counter";export const [ useGlobalContext, GlobalContextProvider ] = createGlobalContext({
counter: {
reducer: counterReducer,
initialState: initialCounterState
},
});
const App = () => (
)
const Counter = () => {
// You can get the state value of the context as follows
const count = useGlobalContext(({ state }) => state.counter.count);
return
count: {count}
;
};const CounterButton = () => {
const counterDispatch = useGlobalContext(({ dispatch }) => dispatch.counter);
return (
<>
>
);
};
`
Examples
$3
This is an example of a counter app that uses the createGlobalContext API.
API
$3
createGlobalContext is an API that generate useGlobalContext hooks with each reducer and initialState of the argument.`javascript
import { createGlobalContext } from "use-global-context";import { counterReducer, counterInitialState } from './reducer/counter'
import { messageReducer, messageInitialState } from './reducer/message'
import { appReducer, appInitialState } from './reducer/app'
export const [ useGlobalContext, GlobalContextProvider, stateController ] = createGlobalContext({
counter: {
reducer: counterReducer,
initialState: counterInitialState,
},
app: {
reducer: appReducer,
initialState: appInitialState,
},
});
`$3
`js
const state = useGlobalContext(selector, equalityFunction);
`this hooks is for Get the state from
GlobalContextProvider.$3
- selector (type: (store: Store) => SelectedStore)
- Specifies the value to be extracted from the store.-
equalityFunction (type: ((a: any, b: any) => boolean) | undefined)
- Specifies how to compare whether to re-render or not. The default is to compare with ===.
$3
- state (type: SelectedStore)
- Return value of the function specified by selector.$3
`javascript
const state = useGlobalContext(({ state, dispatch }) => state);
// {
// counter: {
// count: 100,
// error: null,
// status: null,
// },
// app: {
// name: 'use-global-context',
// description: 'A easy global state management library'
// }
// }const count = useGlobalContext(({ state, dispatch }) => state.counter.count);
// 100
const counterObject = useGlobalContext(({ state, dispatch }) => state.counter, someDeepEqualFunction);
// {
// count: 100,
// error: null,
// status: null,
// }
const dispatch = useGlobalContext(({ state, dispatch }) => dispatch)
// Each of the dispatch functions
// {
// counter: ƒ dispatchAction,
// message: ƒ dispatchAction,
// app: ƒ dispatchAction
// }
const counterDispatch = useGlobalContext(({ state, dispatch }) => dispatch.counter);
// counter: ƒ dispatchAction,
`$3
`js
() => (
{children}
)
`GlobalContextProvider is the provider that stores for the useGlobalContext.$3
stateController included some function that manage state value of useGlobalConext.$3
`javascript
const contextValue = {
counter: {
reducer: counterReducer,
initialState: {
count: 0
}
},
}const [
useGlobalContext,
GlobalContextProvider,
stateController
] = createGlobalContext(contextValue);
// You can get the value of store.
const store = stateController.getState()
// {
// counter: {
// count: 0
// }
// }
// You can override the state.
stateController.setState({
counter: 100
})
`$3
`js
const mergedInitialState = mergedInitialState(target, source)
`API to merge specific initial states for props passed to createGlobalContext.
This API is useful for inheriting the value of the store from the SSR in the browser.
$3
- target (type: GlobalContextReducers)
- Specifies the value of the base context.-
source (type: PartialState)
- Specifies the state to merge.
$3
- mergedInitialState (type: GlobalContextReducers)
- Value obtained by merging the value of source with that of target$3
`javascript
const contextValue = {
counter: {
reducer: counterReducer,
initialState: {
count: 0
}
},
}const ssrState = {
counter: {
count: 100
}
}
// The initial value of count will be set to 100.
const [
useGlobalContext,
GlobalContextProvider,
] = createGlobalContext(mergeInitialState(contextValue, ssrState));
`TypeScript
$3
You can define the value type of the context as follows.
For example, to define the type of the value of a context created with createGlobalContext, you can use the following.`typescript
import {
createGlobalContext,
GlobalContextValue,
} from 'use-global-context';
import { counterReducer, counterInitialState } from './reducer/counter'
import { messageReducer, messageInitialState } from './reducer/message'
import { appReducer, appInitialState } from './reducer/app'const contextValue = {
counter: {
reducer: counterReducer,
initialState: counterInitialState,
},
message: {
reducer: messageReducer,
initialState: messageInitialState,
},
app: {
reducer: appReducer,
initialState: appInitialState,
},
}
const [ useGlobalContext, GlobalContextProvider ] = createGlobalContext(contextValue);
// You can define like this !!
type GlobalContextValue = GlobalContextValue;
const appNameSelector = (state: GlobalContextValue) => state.app.name
const appName = useGlobalContext(appNameSelector)
``