Skip to content

unadlib/react-iflow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

66 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

React iFlow

The connector for React 🌈 iFlow state management.

Travis Coverage Status npm

React iFlow If you use React and iFlow to manage state, save all kinds of selectors cumbersome, while supporting a variety of user-defined store.

πŸ”₯πŸ”₯πŸ”₯It is a highly efficient and concise React and iFlow store connectorπŸ”₯πŸ”₯πŸ”₯

Features and benefits

  • Least possible time selector
  • Automatic array diff
  • Full support comprehensive selector
  • Support immutable

Install

yarn add react-iflow
//or
npm install --save react-iflow

Getting started

To Edit

The Gist

  • index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Body from './body'
ReactDOM.render(<Body/>, document.getElementById('app'))
  • store.js
import iFlow from 'iflow'

const pipe = iFlow({
  calculate: function (number) {
    this.counter += number
  },
  counter: 0,
})

const store = pipe.create()
export default store
  • body.js
import React, { Component } from 'react'
import flow from 'react-iflow'
import store from './store'

class Body extends Component {
  render () {
    return (
      <div>
        <button onClick={() => this.props.store.calculate(-1)}>-</button>
        {this.props.store.counter}
        <button onClick={() => this.props.store.calculate(1)}>+</button>
      </div>
    )
  }
}

export default flow(store)(Body)

Examples

React with iFlow examples Counter(Online) TODO(Online)

API

flow

It's the standard connector of iFlow store

import flow from 'react-iflow'

flow is higher-order function,and it supports the decorator's writing. If the last one argument of the flow is store, then the connected store will take it precedence.

  • Selector: In fact, in most cases, πŸŽ‰πŸŽ‰πŸŽ‰you don't need to use selectorsπŸŽ‰πŸŽ‰πŸŽ‰, because iFlow will automatically help you diff state to determine if the component is updated, unless you need to compute derived data.

  • Higher-order functions
class CustomComponent extends Component {}
flow(store)(CustomComponent)

If use Provider, you don't need to pass the store argument, unless you need to set the selector.

class CustomComponent extends Component {}
flow()(CustomComponent)

More concise way

import { connect } from 'react-iflow'
class CustomComponent extends Component {}
connect(CustomComponent)
  • Class decorator
@flow()
class CustomComponent extends Component {}
  • User-defined select node store
@flow(store.count)
class CustomComponent extends Component {}
  • With array selectors functions
@flow([(state, props) =>{
  return {
    ...props,
    count: state.count,
  }
}],store)
class CustomComponent extends Component {}
  • With arguments selectors functions
@flow(
  (state, props) =>{
    return {
      ...props,
      count: state.count,
    }
  },
  (state, props) =>{
    return {
      ...props,
      counter: state.count.counter,
    }
  },
  store
)
class CustomComponent extends Component {}

provider

import { Provider } from 'react-iflow'
ReactDOM.render(<Provider store={store}><Body/></Provider>, document.getElementById('app'))
  • Provider depend on the react's context to complete the cross component transfer, and its role is exactly the same as react-redux's Provider if you are familiar with react-redux

connect

import { connect } from 'react-iflow'
class CustomComponent extends Component {}
connect(CustomComponent)

When you call Provider inject store, you can use connect API to quickly connect store to the component, it's simple.

immutable

  • Single-layer immutable store is effective when using immutable

@immutableis a single-layer traversal props, so the mixed structure of the iFlow store and plain objects is invalid.

For example:

class Parent extends Component {
  // this.props.sub is iflow store
  render() {
    return <Sub store={this.props.sub} />
  }
}

@immutable
class Sub extends Component {
  // omit
}

This is effective. But the following example is not valid:

class Parent extends Component {
 // this.props.sub is iflow store
 render() {
   const store = {foo:'bar', sub: this.props.sub}
   return <Sub store={store} />
 }
}

@immutable
class Sub extends Component {
 // omit
}

Of course, if you're not using @immutable You can arbitrarily pass the iFlow store.

  • About the Usage of PureComponent

Because the iFlow connector uses the mutable store by default, So the connector directly with the React.PureComponent connection will not be updated, iFlow connector corresponding component should be react.Component, do not worry, iFlow will automatically diff comparison, it is more efficient and automatic than the light comparison of React.PureComponent.

If you really need to use react.PureComponent, then it is recommended that you could use cooperatively with @immutable. This is a great help in Sub-Component performance optimization.

For example:

@flow(store)
@immutable
class Body extends PureComponent {
  render () {
    return (
      <div>
        <button onClick={() => this.props.store.calculate(-1)}>-</button>
        {this.props.store.counter}
        <button onClick={() => this.props.store.calculate(1)}>+</button>
      </div>
    )
  }
}

License


MIT

Releases

No releases published

Packages

No packages published