UNPKG

omniscient

Version:

A library providing an abstraction for React components for passing the same data structure through the entire component flow using cursors and immutable data structures.

513 lines (322 loc) 16.6 kB
### `omniscient(displayName, mixins, render)` Create components for functional views. The API of Omniscient is pretty simple, you create a Stateless React Component but memoized with a smart implemented `shouldComponentUpdate`. The provided `shouldComponentUpdate` handles immutable data and cursors by default. It also falls back to a deep value check if passed props isn't immutable structures. You can use an Omniscient component in the same way you'd use a React Stateless Function, or you can use some of the additional features, such as string defined display name and pass in life cycle methods. These are features normally not accessible for vanilla Stateless React Components. If you simply pass one cursor, the cursor will be accessible on the `props.cursor` accessor. ### Parameters | param | type | description | | ------------- | ------------ | ----------------------------------------------------------------------------------------- | | `displayName` | String | Component's display name. Used when debug()'ing and by React | | `mixins` | Array,Object | React mixins. Object literals with functions, or array of object literals with functions. | | `render` | Function | Stateless component to add memoization on. | ### Properties | property | type | description | | ----------------------- | -------- | --------------------------------- | | `shouldComponentUpdate` | Function | Get default shouldComponentUpdate | **Returns** `Component`, ### `omniscient.withDefaults(Options)` Create a “local” instance of the Omniscient component creator by using the `.withDefaults` method. This also allows you to override any defaults that Omniscient use to check equality of objects, unwrap cursors, etc. ### Options ```js { // Goes directly to component shouldComponentUpdate: function(nextProps, nextState), // check update cursorField: '__singleCursor', // cursor property name to "unwrap" before passing in to render isNode: function(propValue), // determines if propValue is a valid React node classDecorator: function(Component), // Allows for decorating created class // Passed on to `shouldComponentUpdate` isCursor: function (cursor), // check if is props isEqualCursor: function (oneCursor, otherCursor), // check cursor isEqualImmutable: function (oneImmutableStructure, otherImmutableStructure), // check immutable structures isEqualState: function (currentState, nextState), // check state isImmutable: function (currentState, nextState), // check if object is immutable isEqualProps: function (currentProps, nextProps), // check props isIgnorable: function (propertyValue, propertyKey), // check if property item is ignorable unCursor: function (cursor) // convert from cursor to object } ``` ### Examples #### Un-wrapping curors ```jsx var localComponent = component.withDefaults({ cursorField: 'foobar' }); var Component = localComponent(function (myCursor) { // Now you have myCursor directly instead of having to do props.foobar }); React.render(, mountingPoint); ``` #### Decorating class components ```jsx // Some third party libraries requires you to decorate the // React class, not the created component. You can do that // by creating a decorated component factory var decoratedComponent = component.withDefaults({ classDecorator: compose(Radium, function (Component) { var DecoratedComponent = doSomething(Component); return DecoratedComponent; }) }); var Component = decoratedComponent(function (props) { // ... some implementation }); React.render(, mountingPoint); ``` ### Parameters | param | type | description | | --------- | ------ | --------------------------------- | | `Options` | Object | Options with defaults to override | ### Properties | property | type | description | | ----------------------- | -------- | --------------------------------- | | `shouldComponentUpdate` | Function | Get default shouldComponentUpdate | **Returns** `Component`, ### `omniscient(classDecorator, [displayName], [mixins], [render])` Create components for functional views, with an attached local class decorator. Omniscient uses a `createClass()` internally to create an higher order component to attach performance boost and add some syntactic sugar to your components. Sometimes third party apps need to be added as decorator to this internal class. For instance Redux or Radium. This create factory behaves the same as normal Omniscient.js component creation, but with the additional first parameter for class decorator. The API of Omniscient is pretty simple, you create a Stateless React Component but memoized with a smart implemented `shouldComponentUpdate`. The provided `shouldComponentUpdate` handles immutable data and cursors by default. It also falls back to a deep value check if passed props isn't immutable structures. You can use an Omniscient component in the same way you'd use a React Stateless Function, or you can use some of the additional features, such as string defined display name and pass in life cycle methods. These are features normally not accessible for vanilla Stateless React Components. If you simply pass one cursor, the cursor will be accessible on the `props.cursor` accessor. #### Decorating class components ```jsx // Some third party libraries requires you to decorate the // React class, not the created component. You can do that // by creating a decorated component factory var someDecorator = compose(Radium, function (Component) { var DecoratedComponent = doSomething(Component); return DecoratedComponent; }); var Component = component.classDecorator(someDecorator, function (props) { // ... some implementation }); React.render(, mountingPoint); ``` Also works by creating a component factory: ```jsx var someDecorator = compose(Radium, function (Component) { var DecoratedComponent = doSomething(Component); return DecoratedComponent; }); var newFactory = component.classDecorator(someDecorator); var Component = newFactory(function (props) { // ... some implementation }); React.render(, mountingPoint); ``` ### Parameters | param | type | description | | ---------------- | ------------ | ----------------------------------------------------------------------------------------------------- | | `classDecorator` | Function | Decorator to use for internal class (e.g. Redux connect, Radium) | | `[displayName]` | String | _optional:_ Component's display name. Used when debug()'ing and by React | | `[mixins]` | Array,Object | _optional:_ React mixins. Object literals with functions, or array of object literals with functions. | | `[render]` | Function | _optional:_ Stateless component to add memoization on. | ### Properties | property | type | description | | ----------------------- | -------- | --------------------------------- | | `shouldComponentUpdate` | Function | Get default shouldComponentUpdate | **Returns** `Component,Function`, ### `omniscient.debug(pattern)` Activate debugging for components. Will log when a component renders, the outcome of `shouldComponentUpdate`, and why the component re-renders. ### Example ```js Search>: shouldComponentUpdate => true (cursors have changed) Search>: render SearchBox>: shouldComponentUpdate => true (cursors have changed) SearchBox>: render ``` ### Parameters | param | type | description | | --------- | ------ | --------------------------------------------------- | | `pattern` | RegExp | Filter pattern. Only show messages matching pattern | ### Example ```js omniscient.debug(/Search/i); ``` **Returns** `Immstruct`, ### `Component(displayName, props, ...rest)` Invoke component (rendering it) ### Parameters | param | type | description | | ------------- | ------ | ------------------------------------------------------------------------------------------ | | `displayName` | String | Component display name. Used in debug and by React | | `props` | Object | Properties (triggers update when changed). Can be cursors, object and immutable structures | | `...rest` | Object | Child components (React elements, scalar values) | **Returns** `ReactElement`, ### `shouldComponentUpdate(nextProps, nextState)` Directly fetch `shouldComponentUpdate` mixin to use outside of Omniscient. You can do this if you don't want to use Omniscients syntactic sugar. ### Parameters | param | type | description | | ----------- | ------ | --------------------------------------------------------------------- | | `nextProps` | Object | Next props. Can be objects of cursors, values or immutable structures | | `nextState` | Object | Next state. Can be objects of values or immutable structures | ### Properties | property | type | description | | ------------------ | -------- | ---------------------------- | | `isCursor` | Function | Get default isCursor | | `isEqualState` | Function | Get default isEqualState | | `isEqualProps` | Function | Get default isEqualProps | | `isEqualCursor` | Function | Get default isEqualCursor | | `isEqualImmutable` | Function | Get default isEqualImmutable | | `isImmutable` | Function | Get default isImmutable | | `isIgnorable` | Function | Get default isIgnorable | | `debug` | Function | Get default debug | **Returns** `Component`, ### `shouldComponentUpdate.withDefaults([Options])` Create a “local” instance of the shouldComponentUpdate with overriden defaults. ### Options ```js { isCursor: function (cursor), // check if is props isEqualCursor: function (oneCursor, otherCursor), // check cursor isEqualImmutable: function (oneImmutableStructure, otherImmutableStructure), // check immutable structures isEqualState: function (currentState, nextState), // check state isImmutable: function (currentState, nextState), // check if object is immutable isEqualProps: function (currentProps, nextProps), // check props isIgnorable: function (propertyValue, propertyKey), // check if property item is ignorable unCursor: function (cursor) // convert from cursor to object } ``` ### Parameters | param | type | description | | ----------- | ------ | --------------------------------------------- | | `[Options]` | Object | _optional:_ Options with defaults to override | **Returns** `Function`, shouldComponentUpdate with overriden defaults ### `shouldComponentUpdate.isEqualState(value, other)` Predicate to check if state is equal. Checks in the tree for immutable structures and if it is, check by reference. Does not support cursors. Override through `shouldComponentUpdate.withDefaults`. ### Parameters | param | type | description | | ------- | ------ | ----------- | | `value` | Object | | | `other` | Object | | **Returns** `Boolean`, ### `shouldComponentUpdate.isEqualProps(value, other)` Predicate to check if props are equal. Checks in the tree for cursors and immutable structures and if it is, check by reference. Override through `shouldComponentUpdate.withDefaults`. ### Parameters | param | type | description | | ------- | ------ | ----------- | | `value` | Object | | | `other` | Object | | **Returns** `Boolean`, ### `shouldComponentUpdate.isEqualCursor(a, b)` Predicate to check if cursors are equal through reference checks. Uses `unCursor`. Override through `shouldComponentUpdate.withDefaults` to support different cursor implementations. ### Parameters | param | type | description | | ----- | ------ | ----------- | | `a` | Cursor | | | `b` | Cursor | | **Returns** `Boolean`, ### `shouldComponentUpdate.isEqualImmutable(a, b)` Predicate to check if immutable structures are equal through reference checks. Override through `shouldComponentUpdate.withDefaults` to customize behaviour. ### Parameters | param | type | description | | ----- | --------- | ----------- | | `a` | Immutable | | | `b` | Immutable | | **Returns** `Boolean`, ### `shouldComponentUpdate.isImmutable(value)` Predicate to check if a potential is an immutable structure or not. Override through `shouldComponentUpdate.withDefaults` to support different cursor implementations. ### Parameters | param | type | description | | ------- | -------------- | ---------------------------- | | `value` | maybeImmutable | to check if it is immutable. | **Returns** `Boolean`, ### `shouldComponentUpdate.unCursor(cursor)` Transforming function to take in cursor and return a non-cursor. Override through `shouldComponentUpdate.withDefaults` to support different cursor implementations. ### Parameters | param | type | description | | -------- | ------ | ------------ | | `cursor` | cursor | to transform | **Returns** `Object,Number,String,Boolean`, ### `shouldComponentUpdate.isCursor(potential)` Predicate to check if `potential` is Immutable cursor or not (defaults to duck testing Immutable.js cursors). Can override through `.withDefaults()`. ### Parameters | param | type | description | | ----------- | --------- | --------------------- | | `potential` | potential | to check if is cursor | **Returns** `Boolean`, ### `shouldComponentUpdate.isIgnorable(value, key)` Predicate to check if a property on props should be ignored or not. For now this defaults to ignore if property key is `statics`, but that is deprecated behaviour, and will be removed by the next major release. Override through `shouldComponentUpdate.withDefaults`. ### Parameters | param | type | description | | ------- | ------ | ----------- | | `value` | Object | | | `key` | String | | **Returns** `Boolean`, ### `cached(Function)` Directly fetch `cache` to use outside of Omniscient. You can do this if you want to define functions that caches computed result to avoid recomputing if invoked with equal arguments as last time. Returns optimized version of given `f` function for repeated calls with an equal inputs. Returned function caches last input and a result of the computation for it, which is handy for optimizing `render` when computations are run on unchanged parts of state. Although note that only last result is cached so it is not practical to call it mulitple times with in the same `render` call. ### Parameters | param | type | description | | ---------- | -------- | ------------------------ | | `Function` | Function | that does a computation. | **Returns** `Function`, Optimized function ### `cached.withDefaults([Options])` Create a “local” instance of the `cache` with overriden defaults. ### Options ```js { isEqualProps: function (currentProps, nextProps), // check props } ``` ### Parameters | param | type | description | | ----------- | ------ | --------------------------------------------- | | `[Options]` | Object | _optional:_ Options with defaults to override | **Returns** `Function`, cached with overriden defaults ## Private members ### `isNode(propValue)` Predicate showing whether or not the argument is a valid React Node or not. Can be numbers, strings, bools, and React Elements. React's isNode check from ReactPropTypes validator but adjusted to not accept objects to avoid collision with props. ### Parameters | param | type | description | | ----------- | ------ | ---------------------------------------------- | | `propValue` | String | Property value to check if is valid React Node | **Returns** `Boolean`,