use-global-state-context v0.3.0
use-global-state-context
Use-global-state-context is a new way to use useContext better.
Features
- Easy state management with
useStateanduseReducer. - Optimally split context to prevent unnecessary renders.
useSelectorfunction.- Support for SSR.
Why
The context API allows you to create a simple store in combination with hooks such as useState and useReducer.
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 solutions.
On the other hand, while redux is appropriate for managing large amounts of state, I don't think it's necessary for small projects to adopt such a large library.
This library is intended to avoid the implementation costs of redux and also to prevent unnecessary renders, which is a problem with the context API.
Installation
You can install the package from npm.
npm install use-global-state-contextor using yarn.
yarn add use-global-state-contextUsage
General
import React from "react";
import { createUseStateContext } from "use-global-state-context";
// You can add global state here. easy !!
const [useGlobalState, useGlobalDispatch, ContextProvider] = createUseStateContext({
counter: 0,
message: "",
app: {
name: "use-global-state-context",
description: "A easy global state management library",
},
});
const App = () => (
<ContextProvider>
<AppName />
<Counter />
<CounterButton />
</ContextProvider>
)
const Counter = () => {
// You can get the state value of the context as follows
const counter = useGlobalState.counter();
return <p>counter: {counter}</p>;
};
const CounterButton = () => {
// It only gets the dispatch; separating the state and the dispatch prevents extra renders.
const dispatch = useGlobalDispatch();
return (
<>
<button onClick={() => dispatch.counter((counter) => counter + 1)}>+ 1</button>
<button onClick={() => dispatch.counter((counter) => counter - 1)}>- 1</button>
</>
);
};
const AppName = () => {
// Like the redux useSelector API, you can retrieve only the state you need.
// And there are no unnecessary renders.
const name = useGlobalState.app((app) => app.name);
return <p>App: {name}</p>;
};
export default App;createUseStateContext API
createUseStateContext is generated by executing the values of the passed object as useState arguments, each of which is divided with appropriate granularity as a value of context.
import React from "react";
import { createUseStateContext } from "use-global-state-context";
const [useGlobalState, useGlobalDispatch, ContextProvider] = createUseStateContext({
counter: 0,
message: "",
app: {
name: "use-global-state-context",
description: "A easy global state management library",
}
});You can use it as follows.
const counter = useGlobalState.counter();
// 0
const message = useGlobalState.message();
// ""
const appState = useGlobalState.app();
// {
// name: "use-global-state-context",
// description: "A easy global state management library",
// }
const appName = useGlobalState.app(app => app.name)
// "use-global-state-context"
const dispatch = useGlobalDispatch()
// Each of the dispatch functions
// {
// counter: ƒ dispatchAction,
// message: ƒ dispatchAction,
// app: ƒ dispatchAction
// }createUseReducerContext API
createUseReducerContext is createUseStateContext as well as generated by executing the values of the passed object as useReducer arguments, each of which is divided with appropriate granularity as a value of context.
import React from "react";
import { createUseReducerContext } from "use-global-state-context";
const initialState = {
count: 0,
};
const ActionType = {
INCREMENT: "INCREMENT",
DECREMENT: "DECREMENT",
} as const;
type CounterAction = {
type: keyof typeof ActionType;
};
const reducer: React.Reducer<typeof initialState, CounterAction> = (
state,
action
) => {
switch (action.type) {
case ActionType.INCREMENT: {
return {
count: state.count + 1,
};
}
case ActionType.DECREMENT: {
return {
count: state.count - 1,
};
}
default: {
return state;
}
}
};
export const [useGlobalState, useGlobalDispatch, ContextProvider] = createUseReducerContext({
counter: {
reducer,
initialState,
}
});The usage is the same as useCreateReducerContext API.
Examples
CreateUseStateContext API example
This is an example of a counter app that uses the createUseStateContext API.
Notice that each time you increase/decrease the count, only the render of the Counter comport is running. (No unnecessary renders are happening.)
CreateUseReducerContext API example
Similar to the example above, this is an example of a counter app using the createUseReducerContext API.
License
5 years ago