preact-cycle

0.5.1 • Public • Published

preact-cycle

NPM travis-ci

Minimal functional (-reactive) Virtual DOM rendering using Preact.


Simple Example

View this example on esnextb.in

import { render, h } from 'preact-cycle';
/** @jsx h */
 
const App = ({ value, mutation }) => (
  <div>
    <p>Value: { value }</p>
    <button onClick={ mutation('value', v => v+1) }>Increment</button>
  </div>
);
 
render(App, { value: 0 });

To-Do List Example

A simple example, where reducers are just pure functions. Note that TOGGLE mutates state in-place, which works fine but is discouraged.

View this example on esnextb.in

import { render, h } from 'preact-cycle';
/** @jsx h */
 
const ADD = ({ text, todos, ...state }) => ({
  todos: todos.concat({ text }),
  text: '',
  ...state
});
 
const TOGGLE = (state, todo) => {
  todo.done = !todo.done;
  return state;
};
 
const REMOVE = ({ todos, ...state }, todo) => ({
  todos: todos.filter( t => t!==todo ),
  ...state
});
 
 
const TodoList = ({ text, todos, mutate, mutation }) => (
  <div>
    <form onSubmit={mutation(ADD)} action="javascript:">
      <input value={text} onInput={e => mutate('text', e.target.value)} />
      <button action="submit">Add</button>
    </form>
    <ul>
      { todos.map( todo => (
        <li onClick={mutation(TOGGLE, todo)}>
          <input type="checkbox" checked={todo.done} readonly />
          <p>{ todo.text }</p>
          <a onClick={mutation(REMOVE, todo)}></a>
        </li>
      ))}
    </ul>
  </div>
);
 
render(TodoList, { todos: [] }, document.body);

Component-Based Example

Normal preact components still work great with preact-cycle. As of v0.4, mutate() and mutation() are conveniently available as context properties, which means they are automatically passed down through the VDOM tree. For pure functional components, context is simply passed as a second argument.

A component-based variant of the previous To-Do List example follows, using pure functions and context.

View this example on Webpackbin

import { h, render } from 'preact-cycle';
/** @jsx h */
 
 
/** initial data to populate the store */
const INITIAL_DATA = {
  todos: [
    { text:'Type some text' },
    { text:'...then hit [enter]' },
    { text:'Now you\'re productive!' }
  ]
};
 
/** Appends a new todo item */
const ADD = ({ todos, text, ...state }) => ({
  todos: todos.concat({ text }),
  text: '',
  ...state
});
 
/** Remove the given todo item */
const REMOVE = ({ todos, ...state }, todo) => ({
  todos: todos.filter(t => t!==todo),
  ...state
});
 
/** Toggles the given todo item as done */
const TOGGLE = (state, todo) => {
  todo.done = !todo.done;
};
 
 
/** a simple helper to derive a mutated value from an event */
let fromEvent = (prev, e) => e.target.value;
 
 
/** The todo list app */
const App = ({ text, todos }) => (
  <div id="app">
    <Form text={text} />
    <ul>{ todos.map( todo => (
      <Item todo={todo} />
    )) }</ul>
  </div>
);
 
/** New todo entry form */
const Form = ({ text }, { mutation }) => (
  <form onSubmit={mutation(ADD)} action="javascript:">
    <input placeholder="New item..."
      value={text}
      onInput={mutation('text', fromEvent)} />
  </form>
);
 
/** A single todo list item */
const Item = ({ todo }, { mutation }) => (
  <li onClick={mutation(TOGGLE, todo)} class={{ done: todo.done }}>
    <input type="checkbox" checked={todo.done} readonly />
    <a onClick={mutation(REMOVE, todo)}></a>
    <p>{ todo.text }</p>
  </li>
);
 
// Kick off the cycle!
render(App, INITIAL_DATA, document.body);

License

MIT

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 0.5.1
    95
    • latest

Version History

Package Sidebar

Install

npm i preact-cycle

Weekly Downloads

95

Version

0.5.1

License

MIT

Last publish

Collaborators

  • developit