
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
use-global-context
Advanced tools
Use-global-context is a new way to use useContext better with selector.
useSelector function.The 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.
You can install the package from npm.
npm install use-global-context
or
yarn add use-global-context
The first step is to define the reducer and its state.
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.
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 = () => (
<GlobalContextProvider>
<Counter />
<CounterButton />
</GlobalContextProvider>
)
const Counter = () => {
// You can get the state value of the context as follows
const count = useGlobalContext(({ state }) => state.counter.count);
return <p>count: {count}</p>;
};
const CounterButton = () => {
const counterDispatch = useGlobalContext(({ dispatch }) => dispatch.counter);
return (
<>
<button onClick={() => counterDispatch(incrementCount())}>+ 1</button>
<button onClick={() => counterDispatch(decrementCount())}>- 1</button>
</>
);
};
This is an example of a counter app that uses the createGlobalContext API.
createGlobalContext APIcreateGlobalContext is an API that generate useGlobalContext hooks with each reducer and initialState of the argument.
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,
},
});
useGlobalContext hooksconst state = useGlobalContext(selector, equalityFunction);
this hooks is for Get the state from GlobalContextProvider.
selector (type: (store: Store) => SelectedStore)
equalityFunction (type: ((a: any, b: any) => boolean) | undefined)
===.state (type: SelectedStore)
selector.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,
GlobalContextProvider() => (
<GlobalContextProvider>
{children}
</GlobalContextProvider>
)
GlobalContextProvider is the provider that stores for the useGlobalContext.
stateControllerstateController included some function that manage state value of useGlobalConext.
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
})
mergeInitialState APIconst 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.
target (type: GlobalContextReducers)
source (type: PartialState<GlobalContextReducers> | undefined)
mergedInitialState (type: GlobalContextReducers)
source with that of targetconst 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));
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.
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<typeof contextValue>;
const appNameSelector = (state: GlobalContextValue) => state.app.name
const appName = useGlobalContext(appNameSelector)
FAQs
A new way to use “useContext” better
We found that use-global-context demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.