...
Clone https://github.com/adamstankiewicz/hooks-context-selectors
npm i
in the root to installnode_modules
npm start
to run the application at http://localhost:8080
Examples
Redux Example
Because the example repo is using
@edx/frontend-platform
to bootstrap the MFE application, we may pass a Redux store to theAppProvider
component insrc/index.jsx
The Redux
store
is defined./src/examples/basic-redux/store.js
Adds a property/namespace
counter
to the store, controlled by a counter-specific reducer.The reducer is defined in
./src/examples/basic-redux/data/counterSlice.js
Created with
createSlice
from@reduxjs/toolkit
, which generates actions to mutate the data in the slice.
The reducer file also exports selector functions (e.g.,
selectCount1
) to use withuseSelector
fromreact-redux
.Each counter component subscribes to the Redux store by extracting the respective count value using
useSelector
and handles decrement/increment clicks by dispatching (viauseDispatch
) an action.When an action is dispatched, the reducer handles the action type and mutates the data existing in the store accordingly.
Tip |
---|
Only the random number for the counter that was interacted with is updated when the counter is decremented/incremented (no-rendering of the other, unrelated counter). |
Basic Hooks + Context Example
Wraps the rendered route a React context provider where the current counter values are stored and accessed from any nested component under the context provider.
The current values of each counter are stored in independent state variables, and passed through the (memoized) context value along with decrement/increment functions for each counter.
The decrement/increment functions simply call the state setters for each count variable.
Both counters are subscribed to the same context, but read different values from the context.
Info |
---|
Only the components nested under a context provider that explicitly subscribe to the context via |
Note |
---|
The random numbers for both counter are updated even though only one counter was interacted with (unnecessarily re-renders the unrelated counter). |
Hooks + Context (with useReducer
)
Wraps the rendered route a React context provider where the current counter values are stored and accessed from any nested component under the context provider.
Rather than defining a count value for each counter in independent state variables, this example defines a reducer with an initial state containing both counters' initial value of
0
. It also defines actions that may be dispatched to mutate each counter value.The current values for each counter as well as the reducer’s
dispatch
function are exposed in the context value for descendent components.Both counters are subscribed to the same context, but read different values from the context.
Note |
---|
The random numbers for both counter are updated even though only one counter was interacted with (unnecessarily re-renders the unrelated counter). |
Hooks + Context (with context selectors)
Wraps the rendered route a React context provider where the current counter values are stored and accessed from any nested component under the context provider.
As opposed to using
useReducer
in the provider, this example instead utilizesuse-context-selector
to create and read from the counter-related context for the route.Github: https://github.com/dai-shi/use-context-selector
For details on how
use-context-selector
works behind-the-scenes, see
Expects the resulting value from React’s
useState
hook to be passed into the context provider’svalue
.
Defines a custom React hook
useCounterActions
to return the relevant decrement/increment actions for each counter as helper for components to mutate the context value.Subscribes to only the relevant slice of the context value in each counter.
...