@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
59 lines (51 loc) • 1.92 kB
text/typescript
import * as React from "react";
import * as R from "ramda";
import { getSetterName, NOOP } from "./helpers";
import { createProvider } from "./provider";
import { createWithConsumerDecorator } from "./withConsumer";
import { createWithProviderDecorator } from "./withProvider";
/**
* Creates a React Context and returns consumer & providers components & decorators to interact
* with this context.
* @param initialContext map of context properties and their initial values
* @param stateValidator optional predicate to tell whether the state update is valid or not
* @returns Object containing the context components & decorators
*/
export function createContext(
initialContext: Record<string, any>,
stateValidator: (
obj: { property: string; value: unknown },
oldValue: unknown
) => boolean = 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(
React.createContext,
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,
};
}