Coder Social home page Coder Social logo

gurkerl83 / keo Goto Github PK

View Code? Open in Web Editor NEW

This project forked from wildhoney/keo

0.0 2.0 1.0 9.46 MB

Plain functions for a more functional Deku approach to creating stateless React components, with functional goodies such as compose, memoize, etc... for free.

Home Page: http://keo-app.herokuapp.com/

License: MIT License

CSS 29.09% HTML 5.21% JavaScript 65.70%

keo's Introduction

Keo

"Keo" is the Vietnamese translation for glue.
Plain functions for a more functional Deku approach to creating stateless React components, with functional goodies such as compose, memoize, etc... for free.

Travis   npm   License MIT

  • npm: npm install keo --save


Table of Contents

At the core of Keo's philosophies is the notion that you shouldn't have to deal with the this keyword — and while in ES2015 the this keyword has become easier to manage, it seems wholly unnecessary in a React component. As such, Keo takes a more Deku approach in that items such as props, context, nextProps, etc... are passed in to some React lifecycle functions.

Since v4.x, Keo has taken on a more fundamental interpretation of React where components are expected to be passed immutable properties — and state is entirely inaccessible, as is setState to prevent components from holding their own state. As such, you are required to use Redux with Keo to pass properties down through your components.

Note: Prior to v4.x Keo had a different API which was more tolerant — please use npm i [email protected]See associated README

Advantages

  • Steer away from class sugaring, inheritance, and super calls;
  • Create referentially transparent, pure functions without this;
  • Gain memoize, compose, et cetera... for gratis with previous;
  • Use export to export plain functions for simpler unit-testing;
  • Simple composing of functions for mixin support;
  • Avoid functions being littered with React specific method calls;
  • Integrated shouldComponentUpdate performing immutable equality checks from propTypes;
  • An assumption that immutable properties are used for performance gains;
  • Use render composition to enable Shadow DOM support in React;

Getting Started

Use Redux to pass down properties through your components, and an immutable solution — such as seamless-immutable or Facebook's Immutable — even Object.freeze can in many cases be perfectly acceptable for getting started.

Once you're setup with Redux, and your project is passing down immutable properties, within your first component you can import stitch from Keo. In the following example we'll assume the immutable property name is being passed down to your component:

import React from 'react';
import { stitch } from 'keo';

const render = ({ props }) => {
    return <h1>{props.name}</h1>
};

export stitch({ render });

In the above example the component will re-render every time properties are updated in your Redux state — even when the name property hasn't been changed. React provides the PureRenderMixin mixin for these instances, and Keo provides a similar solution based on propTypes.

Taking advantage of the shouldComponentUpdate improvement means you must define your propTypes — Keo favours this approach over checking props directly to encourage strictness in component definitions. It's also important to remember that you should enumerate props that are passed to your child components — see React's documentation Advanced Performance.

import React, { PropTypes } from 'react';
import { stitch } from 'keo';

const propTypes = {
    name: PropTypes.string.isRequired
};

const render = ({ props }) => {
    return <h1>{props.name}</h1>
};

export stitch({ propTypes, render });

With the above component definition only when the name property has changed will the component re-render — in many cases this provides a huge performance gain. It's important to benchmark your React applications using tools such as react-addons-perf — and in particular the printWasted function which will demonstrate the benefit of using shouldComponentUpdate.

Destructuring

In keeping with one of Keo's philosophies that the this keyword should be avoided – Keo provides a way to destructure required arguments from within your components:

const componentDidMount = ({ props }) => {
    dispatch(fetch(`/user/${props.user.id}`));
};

Properties which can be destructured are as follows:

  • props which are passed down via Redux;
  • dispatch which is an alias for props.dispatch;
  • context allowing access to such modules as router;

Properties which are typically available in React components, but are unavailable in Keo components:

  • state and setState as stateless components are forbidden to maintain local state;
  • refs use event.target on events instead;
  • forceUpdate as components are only updated via props;

Lifecycle Functions

The entire gamut of React's lifecycle methods pass in their own associated arguments — for example the render method will take props, context and dispatch, whereas other functions such as componentWillUpdate would also take an additional nextProps argument.

Nonstandard Properties

Below are a handful of additional nonstandard properties which can be destructured in all lifecycle methods.

  • id — for managing local state in the Redux tree structure;
  • args — accessing all arguments for passing to other functions;

id

For managing pseudo-local state in a single tree state you can use the id property — which is a unique Symbol representing the current component. When dispatching actions you should pass the id as the payload, and then pass the id back as part of the result — with that information it's simple to determine when a component should be updated.

const render = ({ id }) => {
    return <a onClick={dispatch(setValueFor(id, 'United Kingdom'))}></a>;
};

You may also prevent other components from updating by using the shouldComponentUpdate function to determine when the action applies to the current component. It's worth noting that a custom shouldComponentUpdate will simply be composed with the Keo default shouldComponentUpdate which inspects the propTypes for a significant performance enhancement.

const shouldComponentUpdate = ({ id, props }) => {
    return props.select.id === id;
};

Note: Will also check propTypes if they have been defined on the component.

args

In Haskell you have all@ for accessing all of the arguments in a function, even after listing the arguments individually — with JavaScript you have the nonstandard arguments however with Keo args can be destructured to provide access to all of the arguments passed in, allowing you to forward these arguments to other functions.

const greetingIn = (language, { props }) => {
    switch (language) {
        case 'en': return `Hello ${props.name}`;
        case 'de': return `Guten Tag ${props.name}`;
    }
};

const render = ({ props, context, args }) => {
    const greeting = greetingIn('en', args);
    // ...
    return <h1>${greeting}!</h1>
};

Which then allows you to destructure the arguments in the greetingIn function as though it's a typical lifecycle React method.

Testing Smart Components

Whenever you pass the mapStateToProps argument to Keo's stitch function you create a smart component — due to the wrapping that react-rseredux applies to these components they can be troublesome to test. As such they should ideally be exported as both a smart component for your application and as a dumb component for unit testing.

However Keo provides a convenient unwrap function to resolve smart components to dumb components for testing purposes — leaving your application to handle the smart components.

Component:

import { stitch } from 'keo';

const render = ({ props }) => {
    return <h1>Hi {props.name}</h1>;
};

export default stitch({ render }, state => state);

Unit Test:

import test from 'ava';
import { unwrap } from 'keo';
import Greet from './component';

test('We can unwrap the smart component for testing purposes', t => {

    const UnwrappedGreet = unwrap(Greet);
    const component = <UnwrappedGreet name="Philomena" />;
    
    // ...
    
    t.pass();
    
});

keo's People

Contributors

wildhoney avatar

Watchers

 avatar  avatar

Forkers

digideskio

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.