Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Clone https://github.com/adamstankiewicz/hooks-context-selectors

  2. npm i in the root to install node_modules

  3. npm start to run the application at http://localhost:8080

Examples

Redux Example

Source

  • Because the example repo is using @edx/frontend-platform to bootstrap the MFE application, we may pass a Redux store to theAppProvider component in src/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 with useSelector from react-redux.

    • Each counter component subscribes to the Redux store by extracting the respective count value using useSelector and handles decrement/increment clicks by dispatching (via useDispatch) 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

Source

  • 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 useContext will be re-rendered when the context value changes.

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)

Source

  • 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)

Source

  • 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 utilizes use-context-selector to create and read from the counter-related context for the route.

  • 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.

...