0.0.1-alpha.0 • Published 5 years ago

with-logic v0.0.1-alpha.0

Weekly downloads
5
License
MIT
Repository
github
Last release
5 years ago

with-logic

Functional react state management library, simplify the usage of react-redux and nomalize sync and async actions

usage

install

yarn add with-logic or npm install with-logic --save

import withLogic from 'with-logic';

run demo

yarn add global umi or npm install umi -g

cd demo

umi dev

simple usage

import withLogic from 'with-logic';
import React from 'react';

function add(state, {payload}) {
  return {
    ...state,
    count: payload + state.count
  }
}

function actions({dispatch}) {
  return {
    add: dispatch(add)
  }
}

function initState() {
  return {
    count: 0
  }
}

@withLogic({actions, initState})
export default class extends React.Component {
  render() {
    return (
      <div>
        <button onClick={() => this.props.actions.add(-1)}>-</button>
        <span>{this.props.state.count}</span>
        <button onClick={() => this.props.actions.add(1)}>+</button>
      </div>
    );
  }
}

initState can be an object

const initState = {
  count: 0
}

async action

import React from 'react';
import withLogic, { map } from 'with-logic';
import { users } from '../util/api';
import { compose, curry } from 'ramda';

/**
 *
 * @param {function} fullfiled
 * @param {function} pending
 * @param {function} reject
 */
function makeHandler(fullfiled, pending, reject) {
  return function(state, {payload}, status) {
    if(status === 'FULFILLED') {
      return fullfiled(state, {payload});
    } else if (status === 'PENDING') {
      return pending ? pending(state, {payload}) : {
        ...state,
        isLoading: true
      }
    } else {
      return reject ? reject(state, {paylod}) : {
        ...state,
        isLoading: false
      }
    }
  }
}

const getUsersHandler = makeHandler((state, { payload }) => {
  return {
    ...state,
    users: payload,
    isLoading: false
  }
})

const getUserHandler = makeHandler((state, { payload }) => {
  return {
    ...state,
    isLoading: false,
    user: payload
  }
}, (state, {payload}) => {
  return {
    ...state,
    id: payload,
    isLoading: true
  }
});

function convertUser(user) {
  return {
    id: user.id,
    label: `I'm ${user.name}, I'm ${user.age} years old!`
  }
}

const promiseWithData = curry(function promiseWithData(data, promise) {
  return {
    promise,
    data
  }
})

function actions({dispatch}) {
  return {
    getUsers: compose(dispatch(getUsersHandler), map(convertUser), users.getList),
    getUser: function(id) {
      return compose(dispatch(getUserHandler), promiseWithData(id), users.get)(id);
    }
  }
}

function initState() {
  return {
    users: [],
    user: null,
    id: null
  }
}

@withLogic({actions, initState})
export default class extends React.Component {
  componentDidMount() {
    this.props.actions.getUsers();
  }

  render() {
    const { isLoading, user, users, id } = this.props.state;
    const { getUser } = this.props.actions;
    return <div>
      {
        isLoading ? 'Loading...' : null
      }
      <h3>user list:</h3>
      {
        users.map(user => {
          return <div key={user.id}> {user.label} </div>
        })
      }
      <br/>
      <button onClick={() => { getUser(1) }}>get user(id = 1)</button>
      <div>
        {
          isLoading && id ? `Loading... user(id=${id})` : null
        }
      </div>
      <div>
        {
          user ? JSON.stringify(user) : null
        }
      </div>
    </div>
  }
}

APIS

withLogic: function

map: