UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

73 lines (62 loc) 2.75 kB
import * as React from "react"; import createReactContext from "create-react-context"; import * as R from "ramda"; import { getSetterName, NOOP } from "./helpers"; import { createProvider } from "./provider"; import { createWithConsumerDecorator } from "./withConsumer"; import { createWithProviderDecorator } from "./withProvider"; const reactContextCreator = React.createContext; // Depending on the version of React used, the `createContext` function may not be available // if this is the case, we fall back to a polyfill library const contextCreatorFn = reactContextCreator && typeof reactContextCreator === "function" ? reactContextCreator : createReactContext; /** * @typedef Context * @property {Object} Context.Provider react class component to use as context provider * @property {Function} Context.Consumer react functional component to use as context consumer * @property {Function} Context.withProvider HOC to apply the context provider * @property {function} Context.withConsumer HOC to apply the context consumer. passes the context as props * @property {React.Context} Context.ReactContext React context object * to the wrapped component */ /** * Creates a React Context and returns consumer & providers components & decorators to interact * with this context. * @param {Object} initialContext map of context properties and their initial values * @param {Function} stateValidator optional predicate to tell whether the state update is valid or not * @returns {Context} Object containing the context components & decorators {@link Context} */ export function createContext(initialContext, stateValidator = R.T) { // first we extract the properties name, and create setters name for those const contextPropertiesNames = R.keys(initialContext); const contextSettersNames = R.map(getSetterName, contextPropertiesNames); // we create a React Context with the properties & their setters, assigning a noop function // temporarily (will be overriden by proper setters in the provider component) const ReactContext = R.compose( contextCreatorFn, R.merge(initialContext), R.zipObj(contextSettersNames), R.map(R.always(NOOP)) )(contextSettersNames); // we call the module function to fabricate the Provider & Consumer components const Provider = createProvider({ ReactContext, initialContext, contextPropertiesNames, contextSettersNames, stateValidator, }); const { Consumer } = ReactContext; // and their matching decorators const withProvider = createWithProviderDecorator(Provider); const withConsumer = createWithConsumerDecorator(Consumer); return { Provider, Consumer, withProvider, withConsumer, ReactContext, }; }