Last active
April 9, 2018 09:50
-
-
Save gianmarcotoso/79dd91f2bdbce9be222c9968ca0a68ed to your computer and use it in GitHub Desktop.
Connect React to Redux with Context API
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
import * as React from 'react' | |
import { Store, Unsubscribe, Dispatch } from 'redux' | |
const stateContext = React.createContext() | |
const { Provider, Consumer } = stateContext | |
export interface StateProviderProps<T> { | |
store: Store<T> | |
} | |
export interface ConnectProps<T, S> { | |
select?: (state: T) => S | any | |
children: (slicedState: S, dispatch: Dispatch<any>) => React.ReactNode | |
} | |
export class StateProvider<T> extends React.Component<StateProviderProps<T>, { reduxState: T } > { | |
state = { reduxState: this.props.store && this.props.store.getState() } | |
private unsubscribe: Unsubscribe | |
constructor(props) { | |
super(props) | |
if (!props.store) { | |
throw new Error('Store has not been provided to the StateProvider') | |
} | |
this.unsubscribe = this.props.store.subscribe(() => { | |
this.setState({ reduxState: this.props.store.getState() }) | |
}) | |
} | |
componentWillUnmount() { | |
this.unsubscribe() | |
} | |
render() { | |
return ( | |
<Provider value={{state: this.state.reduxState, dispatch: this.props.store.dispatch}}> | |
{this.props.children} | |
</Provider> | |
) | |
} | |
} | |
export class Connect<T = any, S = any> extends React.Component<ConnectProps<T, S>> { | |
render() { | |
const select = this.props.select || (s => s) | |
const render = this.props.children | |
return <Consumer>{storeContext => render(select(storeContext.state), storeContext.dispatch)}</Consumer> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment