Giter Site home page Giter Site logo

developit / preact-cycle Goto Github PK

View Code? Open in Web Editor NEW
134.0 5.0 12.0 65 KB

:recycle: Minimal functional Virtual DOM rendering using Preact :bike:

Home Page: https://developit.github.io/preact-cycle/

License: MIT License

JavaScript 100.00%
preact preact-components

preact-cycle's Introduction

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 CodePen

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.

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

preact-cycle's People

Contributors

developit avatar jannisg avatar matthewmueller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

preact-cycle's Issues

Webpackbin no longer exists.

You have a few Webpackbin links here, but none of them work because Webpackbin no longer exists. The author decided to drop it and work with the author of Codesandbox.

Trigger a mutation from outside a component

How can I trigger a mutation, for example, after my firebase data is ready?
Mutations on examples are only triggered inside components events.
I've this <div onLoad={fetchData(mutate)} workaround, is this the right approach?

setTimeout vs. requestAnimationFrame?

hey just wondering if there was any reason you went with a setTimeout in the renderer here? just out of simplicity?

I'm thinking requestAnimationFrame might be a bit better (to render on the paints) but i'm not sure if setTimeout was a deliberate decision or not.

Webpack "Module parse failed" import error due to babelHelpers' extends method

I'm trying to upgrade my project from [email protected] to 0.5.0 but as of right now my Webpack 1.13 is throwing an error when trying to do:

import { h, render } from 'preact-cycle';

I've diffed the generated dist/preact-cycle.js file between versions (0.4.1 vs 0.5.0) and have found the issue being with the use of the extends function which in 0.4.1 was done via:

function createCycle(renderer) {
        function render() {
            return clearTimeout(debounce), debounce = null, renderer(babelHelpers["extends"]({
                mutate: mutate,
                mutation: mutation
            }, data));
        }
...

but in 0.5.0 the generated code looks like this:

function createCycle(renderer) {
        function render() {
            return clearTimeout(debounce), debounce = null, renderer(extends({
                mutate: mutate,
                mutation: mutation
            }, data));
        }
...

Note that in 0.5.0 the extends is used as a function directly whereas 0.4.1 is calling it from within the babelHelpers object.

The issue with the more recent version seems to be that the definition of the

var extends = (function() { ...

is below the code being executed and when webpack is parsing the file during the import phase it seems to freak out when it hits this function call.

I've been trying to work out how this has happened/changed but I can't explain it since neither package.json nor .babelrc in the preact-cycle project seems to have changed since the bump to 0.5.0.

Any ideas?

usage with preact-mdl

with import {h,render} from 'preact-cycle' we got [object][object][object] instead of html

async example

Happen to stop by this page when searching for alternative to React + Redux.
This library seems to be really succinct.

Can someone please add an example of async Ajax/Promise call and how to mutate state after success or error in project readme file ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.