Skip to content

Instantly share code, notes, and snippets.

@Volune
Created October 31, 2018 05:37
Show Gist options
  • Save Volune/4b47881a1e84fa6cc6d402d0e45e8871 to your computer and use it in GitHub Desktop.
Save Volune/4b47881a1e84fa6cc6d402d0e45e8871 to your computer and use it in GitHub Desktop.
import React, { Component, useContext, useMemo } from 'react';
import ReduxContext from './ReduxContext';
const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = dispatch => ({ dispatch });
const defaultMergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
{},
ownProps,
dispatchProps,
stateProps,
);
const getComponentName = WrappedComponent => (
WrappedComponent.displayName || WrappedComponent.name || 'Unknown'
);
const connectWithHooks = (
mapStateToProps = defaultMapStateToProps,
mapDispatchToProps = defaultMapDispatchToProps,
mergeProps = defaultMergeProps,
) => WrappedComponent => {
const Wrapper = (ownProps) => {
const { state, dispatch } = useContext(ReduxContext);
const stateProps = useMemo(
() => mapStateToProps(state, ownProps),
[state, ownProps],
);
const dispatchProps = useMemo(
() => mapDispatchToProps(dispatch, ownProps),
[dispatch, ownProps],
);
const mergedProps = useMemo(
() => mergeProps(stateProps, dispatchProps, ownProps),
[stateProps, dispatchProps, ownProps],
);
// this test is constant for all the lifetime of the component
if (typeof WrappedComponent !== 'function' || WrappedComponent instanceof Component) {
return useMemo(() => <WrappedComponent {...mergedProps} />, [mergedProps]);
}
// inline call of the wrapped component
return WrappedComponent(mergedProps);
};
Wrapper.displayName = `connect(${getComponentName(WrappedComponent)})`;
return Wrapper;
};
export default connectWithHooks;
import React from 'react';
const ReduxContext = React.createContext();
export default ReduxContext;
import React, { useMemo } from 'react';
import { connect } from 'react-redux';
import ReduxContext from './ReduxContext';
const mapStateToProps = state => ({ state });
const ReduxProvider = ({ state, dispatch, children }) => {
return useMemo(() => (
<ReduxContext.Provider value={{ state, dispatch }}>
{children}
</ReduxContext.Provider>
), [state, dispatch]);
};
export default connect(mapStateToProps)(ReduxProvider);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment