npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-high-order

v1.2.0

Published

A set of high order react components

Downloads

18

Readme

react-high-order

A set of higher order and render props components that will help increasing your productivity on web development.

npm install --save react-high-order

Why react-high-order exists ?

In my opinion, React is the best tools for creating modular components that can be combined to something bigger and more complex (or maybe because I never use any other front-end library or framework). However, the more you code the more you will ask yourself, "why I have to rewrite the same component or the save behavior for every new project ?". I think it is time for me to create real world reusable react components that contain some logic inside such as a component that can call api and provide status to children, a component that can collect a function and will be called when user click submit. Let's get started

Example

When you want to create a component that contain simple api calling inside a component you would do this

    const api = () => new Promise((resolve) => {
      resolve('response from api');
    });
    
    class Example extends React.Component {
    
      static propTypes = {};
    
      state = {
        status: 'initialized',
        error: null,
        response: null
      };
    
      callApi = () => {
        this.setState({ status: 'requesting' });
        api()
          .then((response) => this.setState({
            response,
            status: 'success'
          }))
          .catch((error) => this.setState({
            error,
            status: 'failure'
          }));
      };
    
      render() {
        const { status, response, error } = this.state;
        return (
          <div>
            <p>{status}</p>
            {response && (
              <p>
                {/* or render something else */}
                {response}
              </p>
            )}
            {error && (
              <p>{error}</p>
            )}
            <button onClick={this.callApi}>
              {status === 'requesting' ? 'Requesting...' : 'Call API'}
            </button>
          </div>
        );
      }
    }

But with react-high-order, you only have to do this

    import { Caller } from 'react-high-order'
    
    const Example = () => (
      <Caller api={api}>
        {(wrappedApi, { status, response, error, reset }) => {
          return (
            <div>
              <p>
                {status.isInitial && 'Initialized'}
                {status.isRequest && 'Requesting'}
                {status.isSuccess && 'Success'}
                {status.isFailure && 'Failed!'}
              </p>
              <p>{response}</p>
              {error && (
                <button onClick={reset}>reset</button>
              )}
              <button onClick={wrappedApi}>
                {status === 'requesting' ? 'Requesting...' : 'Call API'}
              </button>
            </div>
          );
        }}
      </Caller>
    )

What Caller do is just wrapping the api you provide with status and then transfer to its children. This technique is officially called as render props. The code is more cleaner and declarative, you don't have to be overwhelmed with lots of state.

API

Mostly react-high-order components will be hoc or using render props technique. The purpose of this repo is to help you increase your productivity in web development without messing core logic in your app.

TOC

Render Props

Caller

description : accept child only as a function and provide wrappedApi, status, ...others to it.

use case : Call api within component

parameters

| props | type | default | | ------------- |------------- | ----- | | children () | fn(options) => react element | - | | api () | fn => promise | - | | onRequest | fn => void | () => {} | | onSuccess | fn => void | () => {} | | onFailure | fn => void | () => {} |

children options

| parameters | type | initial state | description | | ------------- |------------- | ----- | --- | | wrappedApi | fn | - | the same fn as api from props but wrapped with status | status | object | null | { state:<String: 'isInitial', 'isSuccess', 'isFailure'>, isInitial:<Bool>, isRequest:<Bool>, isSuccess:<Bool>, isFailure:<Bool> } | response | - | null | resolve from api | error | - | null | reject from api | reset | fn | fn | reset status, response, error to initial state |

example

  <Caller api={api}>
    {(wrappedApi, { status, response, error, reset }) => {
      return (
        // You can do whatever you want
        // show status
        // show response
        // show error from api
        // even calling reset  if you want.
      );
    }}
  </Caller>

Notes You can change state of the status by doing this

import { Caller } from 'react-high-order'

Caller.REQUEST = 'isPending'
Caller.SUCCESS = 'isFulfilled'
Caller.FAILURE = 'isFailure'

export default Caller

// then use Caller from above
// the result will be like

import Caller from '../file above';

<Caller>
  {(wrappedApi, { status }) => (
    // status = { isInitial<Bool>, isPending<Bool>, isFulfilled<Bool>, isFailure<Bool> }
  )}
</Caller>

Activator

description accept child only as a function and provide 'createAction' that you can input callback to call.

use case: Show modal before deleting something (great for using with Caller)

parameters

| props | type | default | | ------------- |------------- | ----- | | children () | fn(options) => react element | - | | action () | fn => (promise or void) | - | | actionIsPromise | bool | false | | resetAfterAction | bool or object | false |

children options

| parameters | type | initial state | description | | ------------- |------------- | ----- | --- | | activate | fn | - | set activated to true and can accept params and store it for later use | active | bool | false | a boolean that tell activate sth (such as modal) | createAction | fn | - | the same fn as action from props but wrapped to toggle activated | reset | fn | - | reset to initial state | params | array | null | array of params that you provide when use activate(...params)

example

<Activator actionIsPromise resetAfterAction={{ isRequest: true }}>
    {({ activate, active, params, createAction, reset }) => (
      // params[0] = 'item to delete'
      <div>
        <Modal open={active}>
          <button onClick={createAction(deleteApi)}>call action</button> // deleteApi will receive 'item to delete' as first parameter
          <button onClick={reset}>cancel</button>
        </Modal>  
        <div>
          <button onClick={() => activate('item to delete')}>activate</button>
        </div>
      </div>
    )}
</Activator>

You can change static status in Activator as same as Caller

Collection

description control collection contain adding new item, update, duplicate, remove item

use case: show list in form that user can add more and edit each item

parameters

| props | type | default | | ------------- |------------- | ----- | | children (*) | fn(options) => react element | - | | initialItems | array of string, object | - |

children options

| parameters | type | initial state | description | | ------------- |------------- | ----- | --- | | items | array of string, object | [] | the same format as initialItems | addToIndex | fn(newItem, index) | - | accept 2 params newItem: item that will be added and index: index to be added in front | duplicateIndex | fn(index, callback) | - | accept 2 params index: item index that will be duplicate and callback: (item of that index) => new duplicated Item | onItemChange | fn(newItem<fn, string, object>, predicate) | - | accept 2 params newItem: if it is function accept item that pass predicate and return a new one, else new item predicate a predicate to find item to be changed. | onItemChangeByIndex | fn(newItem<fn, string, object>, index) | - | same as onItemChange but change predicate to index to specify which index to be changed. | removeItem | fn(predicate) | - | accept 2 params item and index return true will remove the item | removeIndex | fn(index) | - | remove the item that is the same as index | renderItems | array | - | a wrapped array that can be used for cleaner code, contain all wrapped function item, onDuplicate, onChange, onRemove (check out example for more detail usage)

other methods

| name | type | description | | ------------- |------------- | ----- | | appendDuplicateName | static fn(name) => name (copy) | a util fn for append 'copy' to name (use with duplicate method) | | resetItems | fn(items, callback) | to reset items (using setState internally, so you can inject callback as normal) |

example

  <div>
    <h2>Fully Control</h2>
    <Collection
      ref={this._collection1} // you can use ref to access `resetItems`
      initialItems={this.state.items}
    >
      {({ items, addToIndex, onItemChange, duplicateIndex, removeIndex }) => (
        <div>
          <ul>
            {items.map((item, index) => (
              <li key={index}>
                {item.name}
                <button
                  onClick={() => onItemChange({ name: `${item.name}+` }, (_, i) => index === i)}
                >append +
                </button>
                <button onClick={() => duplicateIndex(index, () => ({ name: Collection.appendDuplicateName(item.name) }))}>dup</button>
                <button onClick={() => removeIndex(index)}>remove</button>
              </li>
            ))}
          </ul>
          <button onClick={() => addToIndex({ name: 'test' })}>
            add
          </button>
        </div>
      )}
    </Collection>
    <button onClick={this.reassignItems1}>reset</button>
    <hr />
    <h2>Light Version</h2>
    <Collection
      ref={this._collection2}
      initialItems={this.state.items}
    >
      {({ renderItems, addToIndex }) => (
        <div>
          <ul>
            {renderItems.map((source, index) => {
              const { item, onChange, onRemove, onDuplicate } = source;
              return (
                <li key={index}>
                  {item.name}
                  <button
                    onClick={() => onChange({ name: `${item.name}+` })}
                  >append +
                  </button>
                  <button onClick={() => onDuplicate({ name: Collection.appendDuplicateName(item.name) })}>
                    dup
                  </button>
                  <button onClick={onRemove}>remove</button>
                </li>
              );
            })}
          </ul>
          <button onClick={() => addToIndex({ name: 'test' })}>
            add
          </button>
        </div>
      )}
    </Collection>
    <button onClick={this.reassignItems2}>reset</button>
  </div>