-
Notifications
You must be signed in to change notification settings - Fork 258
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert state providers to use
use-context-selector
This user-land library improves performance by removing unnecessary re-renders to components which use global contexts. By selecting the state that the components use from the contexts, they'll limit their re-rendering to only when that state changes. See reactjs/rfcs#119 for more relevant information about the performance issues with the context API.
- Loading branch information
1 parent
b230303
commit ca838b7
Showing
12 changed files
with
178 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,29 @@ | ||
import React, { useContext } from 'react' | ||
import React from 'react' | ||
import { createContext, useContextSelector } from 'use-context-selector' | ||
|
||
type Selector<State> = <T>(selector: (state: State) => T) => T | ||
/** | ||
* This creates a "state provider" component from a getter function. | ||
* The function passed is a getter function to return the value for the state | ||
* provider's context. | ||
* | ||
* @param getValue the function to return the context value | ||
* @returns The context provider component and a useContextValue hook | ||
* @param getState the function to return the context value (state) | ||
* @returns The context provider component and a useStateSelector hook to select context state | ||
*/ | ||
export function createStateProvider<Value>(getValue: () => Value): [React.FunctionComponent<{ children: React.ReactNode }>, () => Value] { | ||
const Context = React.createContext<Value | undefined>(undefined) | ||
export function createStateProvider<State>(getState: () => State): [React.FunctionComponent<{ children: React.ReactNode }>, Selector<State>] { | ||
const Context = createContext<State | undefined>(undefined) | ||
function WithContext({ children }: { children: React.ReactNode }) { | ||
const value = getValue() | ||
const value = getState() | ||
return <Context.Provider value={value}>{children}</Context.Provider> | ||
} | ||
|
||
function useContextValue() { | ||
const context = useContext(Context) | ||
if (context == null) throw new Error(`Cannot call useDefinedContext outside of ${Context.displayName}`) | ||
return context | ||
function useStateSelector<T>(selector: (state: State) => T): T { | ||
const state = useContextSelector(Context, state => { | ||
if (state == null) throw new Error(`Cannot call useStateSelector outside of ${Context.displayName}`) | ||
return selector(state) | ||
}) | ||
return state | ||
} | ||
|
||
return [WithContext, useContextValue] | ||
return [WithContext, useStateSelector] | ||
} |
Oops, something went wrong.