Skip to content

Instantly share code, notes, and snippets.

@zerobias
Last active May 23, 2018 19:25
Show Gist options
  • Save zerobias/701fabcab4af2c97a3356273192d98ff to your computer and use it in GitHub Desktop.
Save zerobias/701fabcab4af2c97a3356273192d98ff to your computer and use it in GitHub Desktop.
Indux

Indux concept

Declarative, memoized, null-safe state selectors for redux and react-redux

API

shape

Create shape of redux store to make requests

connectLens

Connect from react-redux, but simplified recieves object with lenses, made component props from them

import { stateShape, Client, Order } from '../store'

type OrdersProps = {
  orderId: number,
  hasDiscount: boolean,
}

const AllOrders = stateShape
  .orders
  .select((orders, { orderId }) => orders.get(orderId))

const AllOrders = stateShape
  .orders
  .get(props => props.orderId)

const AllOrders = stateShape
  .orders
  .get(props.orderId)
  

const AllOrders = stateShape
  .orders
  .select(
  .get(props.orderId)

const AllOrders = stateShape
  .orders(find(props => props.orderId))
   

Actions and upshots

Redux introduced conception of action types which assumed to use in action creators. In fact, we just need to describe expected types, and what will happens upshot.

Action

action creator and action type simultaneously

Used to create upshots - typical redux actions, and referenced as action type itself; you don't need to compare strings or made directory for constants

export type Upshot<P> = {
  type: string,
  payload: P,
}

export type Action<P> = {
  (payload: P): Upshot<P>,
  getType(): string,
}

declare export function creacteAction<P>(actionDescription?: string): Action<P>
// actions.js
import { creacteAction, Action } from 'indux'

type Message = {
  to: number,
  text: string,
}

export const sendMessage: Action<Message> = createAction('send message')

// -> function (payload) { ... }
import { sendMessage } from './action'

sendMessage({ to: 1337, text: 'Message to ID 1337' })

/* ->  {
  type: '[01] send message',
  payload: {
    to: 1337,
    text: 'Message to ID 1337',
  },
}
*/
import { stateShape } from '../store'
type ClientOrdersProps = {
orders: number[],
id: number,
}
const ClientOrders = ({ orders, id }: ClientOrdersProps) =>
<div>
{orders.map( order => <div>{order}</div> )}
</div>
// client -- is a function (lense) which
// returns Client object (user scope)
// for any recieved user
type ClientLens = (state: State, props: { id: number }) => Client
const client: ClientLens =
stateShape
.clients
.select(props => props.id)
// orders - is a function for selecting
// array of orders for any recieved user
type ClientOrders = (state: State, props: { id: number }) => number[]
const orders: ClientOrders = client.orders
// connectLens -- is a connect from react-redux, but simplified
// recieves object with lenses
const ClientOrdersContainer =
connectLens({ orders })( ClientOrders )
export default ClientOrdersContainer
import ClientOrders from './ClientOrders'
export const Page = ({ userId }: { userId: number }) =>
<div>
<h1>Client {userId}</h1>
<ClientOrders id={userId} />
</div>
import {
createStore,
combineReducers,
type Store,
} from 'redux'
import reducers from './reducers' // some common reducers
import { shape } from 'indux'
export type Client = {
id: number,
orders: number[],
}
export type Order = {
id: number,
client: number,
}
export type State = {
orders: Map<number, Order>,
clients: Map<number, Client>,
}
const opticShape = {
orders: {
get: (orders, order) => orders.get(order.id),
set: (orders, order) => orders.set(order.id, order),
},
clients: {
get: (clients, client) => clients.get(client.id),
set: (clients, client) => clients.set(client.id, client),
},
}
const store: Store<State, *, *> = createStore(reducers)
export const stateShape = shape(store)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment