UNPKG

undux

Version:

Dead simple state management for React

63 lines 2.85 kB
import * as React from 'react'; import { createStore, } from '..'; import { getDisplayName, mapValues } from '../utils'; export function createConnectedStoreAs(initialStates, effects) { let Context = React.createContext({ __MISSING_PROVIDER__: true }); class Container extends React.Component { constructor(props) { super(props); // Create store definition from initial state let states = props.initialStates || initialStates; let stores = mapValues(states, (_) => createStore(_)); // Apply effects? let fx = props.effects || effects; if (fx) { fx(stores); // TODO } this.state = { storeDefinitions: stores, // TODO storeSnapshots: mapValues(stores, (_) => _.getCurrentSnapshot()), subscriptions: mapValues(stores, (_, k) => _.onAll().subscribe(() => this.setState((state) => ({ storeSnapshots: Object.assign({}, state.storeSnapshots, { [k]: _.getCurrentSnapshot(), }), })))), }; } componentWillUnmount() { mapValues(this.state.subscriptions, (_) => _.unsubscribe()); // Let the state get GC'd. // TODO: Find a more elegant way to do this. mapValues(this.state.storeSnapshots, (_) => (_.state = null)); mapValues(this.state.storeSnapshots, (_) => (_.storeDefinition = null)); mapValues(this.state.storeDefinitions, (_) => (_.storeSnapshot = null)); } render() { return (React.createElement(Context.Provider, { value: this.state.storeSnapshots }, this.props.children)); } } let Consumer = (props) => (React.createElement(Context.Consumer, null, (stores) => { if (!isInitialized(stores)) { throw Error(`[Undux] Component "${props.displayName}" does not seem to be nested in an Undux <Container>. To fix this error, be sure to render the component in the <Container>...</Container> component that you got back from calling createConnectedStoreAs().`); } return props.children(stores); })); function withStores(Component) { let displayName = getDisplayName(Component); let f = (props) => (React.createElement(Consumer, { displayName: displayName }, (stores) => React.createElement(Component, { ...stores, ...props }))); f.displayName = `withStores(${displayName})`; return f; } return { Container, useStores() { return React.useContext(Context); }, withStores, }; } function isInitialized(store) { return !('__MISSING_PROVIDER__' in store); } //# sourceMappingURL=createConnectedStoreAs.js.map