Skip to content

Instantly share code, notes, and snippets.

@marcins
Last active February 2, 2018 06:27
Show Gist options
  • Save marcins/17f693f63c192fd2d13d73e21cd745d6 to your computer and use it in GitHub Desktop.
Save marcins/17f693f63c192fd2d13d73e21cd745d6 to your computer and use it in GitHub Desktop.
Unstated "Connect"
// @flow
import * as React from "react";
import { Subscribe, type ContainerType, type ContainersType } from "unstated";
type ContainerMapping = { [key: string]: ContainerType };
type ConnectTo = ContainerMapping[];
const Connect = ({
component,
to,
...ownProps
}: {
component: React.ComponentType<any>,
to: ConnectTo,
ownProps: Object[]
}) => {
const Component = component;
const { props, containers } = to.reduce(
(acc, v) => {
acc.props.push(Object.keys(v)[0]);
// $FlowFixMe Object.values will always be Array<mixed> :( https://github.com/facebook/flow/issues/2221
acc.containers.push(Object.values(v)[0]);
return acc;
},
{ props: [], containers: ([]: ContainersType) }
);
return (
<Subscribe to={containers}>
{(...instances) => {
const containerProps = props.reduce(
(acc, key: string, index) => ((acc[key] = instances[index]), acc),
{}
);
return <Component {...containerProps} {...ownProps} />;
}}
</Subscribe>
);
};
export default Connect;
@marcins
Copy link
Author

marcins commented Feb 2, 2018

Instead of:

<Subscribe to={[ProjectsContainer]}>
    {projects => <ProjectsList projects={projects} />}
</Subscribe>

You can do:

<Connect component={ProjectsList} to={[{ projects: ProjectsContainer }]} />

Is it actually worthwhile to save a bit of boilerplate? Maybe with more containers? Should there be a more Redux-like mapStateToProps type thing to avoid projects.state etc inside the component (and similar to Redux, allow using selectors to make derived props from state)?

🤷‍♂️ Haven't gone deep enough with it yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment