0.2.7 • Published 4 years ago

reenhance-components v0.2.7

Weekly downloads
39
License
MIT
Repository
github
Last release
4 years ago

reenhance-components

CircleCI MIT License

A collection of React components which provide various functionality to child components in JSX/TSX. By using Render Props pattern, those components can be adopted declaratively just by surrounding children.

Works well when you create component which have some local states (e.g. radio group, toggle show/hide) or needs to show contents from APIs without propagating to global state (e.g. suggest, preview).

Installation and Usage

ES6/TS via npm

npm install reenhance-components

CDN

For CDN, you can use unpkg: https://unpkg.com/reenhance-components/umd/index.min.js

The global namespace is ReenhanceComponents:

const { StateProvider, AsyncResolver, DebouncePropagator, ObjectHolder } = ReenhanceComponents;

Documentation

Each components must be instantiated with initial parameters before using them in JSX/TSX.

AsyncResolver

Resolves async function and passes its result to children as props.

Parameters

PropertyTypeRequiredDescription
distinctKeystringNName of prop to detect changes. Subject function is evaluated everytime value of the prop is changed. The default is 'subject'.
initialPropsobjectNInitial props for children

Props

PropertyTypeRequiredDescription
subjectFunctionYAn async function which returns promise to resolve
(other props)anyNArguments of subject

Arguments of children

PropertyTypeDescription
propsobjectResolved object from result of subject

Example

const asyncFetch =
  ({ query }) =>
    fetch(queryToUrl(query))
      .then(res => res.json())
      .catch(err => ({ error: err.toString() }));

const AlbumsAsyncResolver = AsyncResolver('query', { resultCount: 0, results: [] });

const Albums = ({ query }) => (
  <AlbumsAsyncResolver subject={asyncFetch} query={query} >
    {(props) => (
      ...
    )}
  </AlbumsAsyncResolver>
);

StateProvider

Provides local state and updater to children as its props.

Parameters

PropertyTypeRequiredDescription
initialStateanyYInitial state

Props

nothing

Arguments of children

PropertyTypeDescription
stateobjectCurrent state object
setStateFunctionAn updater for state. Takes new state as its argument

Example

const ToggleState = StateProvider(false);

const Toggle = () => (
  <ToggleState>
    {({ state, setState }) => (
      ...
    )}
  </ToggleState>
);

DebouncePropagator

Debounces props propagation for given milliseconds.

See Debounce of ReactiveX docs for more details.

Parameters

PropertyTypeRequiredDescription
initialPropsobjectYInitial props for children

Props

PropertyTypeRequiredDescription
timenumberYDebounce time in milliseconds
(other props)anyNProperties to propagete to children

Arguments of children

PropertyTypeDescription
propsobjectResolved object from result of subject

Example

const SuggestDebounce = DebouncePropagator({ status: 'loading' });

const Suggest = ({ query }) => (
  <SuggestDebounce time={'200'} query={query}>
    {({ query, status }) => ( // Propagation of 'query' is debounced in 200ms
      ...
    )}
  </SuggestDebounce>
);

ObjectWatcher

Watches a property of an object and passes the latest value as an argument to children.

Parameters

PropertyTypeRequiredDescription
targetObjectobjectYImmutable object to watch its property change

Props

PropertyTypeRequiredDescription
watchstringstring[]YName(s) of property to watch
onChangefunctionNCalled when the value of watching props is changed. Call signature is (newValue: any, oldValue: any, propName: string) => void

Arguments of children

PropertyTypeDescription
(any)objectProxied targetObject

Example

const RefWatcher = ObjectWatcher(React.createRef());

const DivRef = () => (
  <RefWatcher watch="current">
    {divRef => (
      <div ref={divRef}>Hello ref.{divRef.current ? divRef.current.toString() : null}</div>
    )}
  </RefWatcher>
);

Compose (beta)

Composes multiple Components which have Render Props as their child.

Props

PropertyTypeRequiredDescription
childreniComponentYA component which have Render Props as their child.
childrenn - 1ComponentYA render function which receives all props from preceding components

Example

const BooleanState = StateProvider<boolean>(true);
const NumericState = StateProvider<number>(3);

const MultiStateDiv = () => (
  <Compose>
    <BooleanState />
    <NumericState />
    {(b: StateAndUpdater<boolean>, n: StateAndUpdater<number>) => (
      <div>
        {b.state.toString()}:{n.state}
      </div>
    )}
  </Compose>
);

FAQ

  • Q: Is this an alternative to Redux?
    A: No. This module doesn't provide global state or flow pattern.
  • Q: Should I use this instead of Redux?
    A: It depends. If the state or API response is local and per-instance, probably this module fits well.
  • Q: Is this better than HoCs?
    A: Not sure. I think they are almost same. 😉
  • Q: Can I rename arguments, 'state' and 'setState' of StateProvider?
    A: Rename them in destructuring like ({ state: isOpen, setState: setIsOpen }).
  • Q: Why StateProvider passes the state as a property of object? It's confusing.
    A: One reason is for renaming. Another reason is state and setState are inseparatable in StateProvider. Try ObjectWatcher if you really don't want to use setState.
  • Q: Why don't you make AjaxResolver? It will be convenient. A: Requesting Ajax causes dependency to other APIs like fetch, fetchJsonp, Axios, etc. This module is intended to solve only common part of problems.

For contributors

This project aims these characteristics.

  • declarative
  • separation of view and logic
  • can coexist with other modules
  • works well with TypeScript

For myself

git push
npm publish
0.2.7

4 years ago

0.2.6

5 years ago

0.2.5

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.9

6 years ago

0.0.8

6 years ago

0.0.7

6 years ago

0.0.6

6 years ago

0.0.5

6 years ago

0.0.4

6 years ago

0.0.3

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago