RoyalIcing / react-organism

Dead simple React state management to bring pure components alive
https://react-organism.now.sh/
MIT License
223 stars 3 forks source link

Add DOM helpers #8

Closed RoyalIcing closed 7 years ago

RoyalIcing commented 7 years ago
import fromForm from 'react-organism/fromForm'

export const addExpense = (props, { description, costCents }) => ({ items }) => ({
  items: items.concat({ description, costCents })
})

// Requires form inputs with names 'description' and 'costCents'
// reset: true will clear the inputs in the form
export const addExpenseFromFormAutomatic = fromForm(addExpense, { reset: true })

export const addExpenseFromFormManual = (props, event) => {
  event.preventDefault()
  const { target: { elements } } = event
  const description = elements.description.value
  const costCents = Math.round(parseFloat(elements.costCents.value) * 100)
  return addExpense(props, { description, costCents })
}
import fromDataset from 'react-organism/useDataset'

export const removeExpenseAtIndex = (props, { index }) => ({ items }) => ({
  items: items.filter((item, currentIndex) => currentIndex !== index)
})

export const removeExpenseUsingDataAttrAuto = fromDataset(removeExpenseAtIndex, (dataset) => ({
  index: parseInt(dataset.index, 10)
}))

export const removeExpenseUsingDataAttrManual = (props, event) => {
  const element = event.target

  const index = parseInt(element.dataset.index, 10)
  return removeExpenseAtIndex(props, index)
}

See: https://codesandbox.io/s/PZx36ZpDy

OR: Add with makeOrganism

makeOrganism(Component, actions, {
  enhance: (actions) => ({
    form: {
      // Adds actions.form.addExpense
      addExpense: fromForm(actions.addExpense)
    },
    dataset: {
      // Adds actions.dataset.removeExpense
      removeExpense: fromDataset(actions.removeExpense, (dataset) => ({
        index: parseInt(dataset.index, 10)
      }))
    }
  })
})

OR: in component

import React from 'react'
import fromForm from 'react-organism/fromForm'
import fromDataset from 'react-organism/fromDataset'
import ExpenseList from '../../components/ExpenseList'
import Dollars from '../../components/Dollars'
import { sumExpenses } from './utils'

export default ({
  items,
  actions
}) => (
<div>
    <h2>Expenses</h2>
    <ExpenseList expenses={ items } onRemoveExpense={
      fromDataset(actions.removeExpense, (dataset) => ({
        index: parseInt(dataset.index, 10)
      }))
    } />
    <h3>Total: <Dollars cents={ sumExpenses(items) } /></h3>
    <form onSubmit={ fromForm(actions.addExpense) }>
      <label>
        {'Cost: '}
        <input type='number' name='costCents' />
      </label>
      <label>
        {'Description: '}
        <textarea name='description' />
      </label>
      <button type='submit'>Add expense</button>
    </form>
  </div>
)
RoyalIcing commented 7 years ago

This has been implemented with the argsExtractDOMValues helper