$30 off During Our Annual Pro Sale. View Details »

Controllable React Components

Controllable React Components

Slides from a presentation about react-controllables.

Originally given at ReactDC on 4/7/2015

Eric Eldredge

April 07, 2015
Tweet

More Decks by Eric Eldredge

Other Decks in Programming

Transcript

  1. With react-controllables
    Controllable
    React Components

    View Slide

  2. HZDG.COM
    LETTERTWO
    ERIC ELDREDGE
    [email protected] HZDG
    PHOTO
    MISSING

    View Slide

  3. The Tao of the React Component
    Props vs State

    View Slide

  4. When do you use
    props vs. state?

    View Slide

  5. Always use props…
    • Enables composition
    • Keeps your React Components pure

    View Slide

  6. …unless you need state
    • Some components are affected by user
    interactions
    • Since props are immutable, interactions
    that change the component must either be
    handled by the parent component, or
    translated to state

    View Slide

  7. React Form Components

    Controlled:
    Uncontrolled:
    Uncontrolled (with a default value):


    View Slide

  8. Interactive Components
    • Controlled Components receive values
    as props
    • Uncontrolled Components keep values
    in state

    View Slide

  9. The best of both worlds
    • An interactive component maintains its
    own state
    • Sometimes it yields control to its parent
    (props)
    • It can be both Controlled and
    Uncontrolled

    View Slide

  10. The best of both worlds:
    react-controllables
    MATTHEWWITHANM
    MATTHEW DAPENA-TRETTER
    github.com/matthewwithanm/react-controllables

    View Slide

  11. Example: TabBar
    • When you click on a tab, it becomes
    selected
    • The other tabs in the bar become
    deselected
    • The selected tab is stored as state in the
    component

    View Slide

  12. class TabBar extends React.Component {
    constructor() {
    super();
    this.state = {selectedIndex: 0};
    }
    handleClick(event) {
    const el = event.target;
    const index = el.parentNode.children.indexOf(el);
    this.setState({selectedIndex: index});
    }
    render() {
    const index = this.state.selectedIndex;
    return (

    Zero!
    One!
    Two!

    );
    }
    }

    View Slide

  13. Example: TabBar
    • This works fine until one day…
    • A new component is introduced to the site
    that also controls which tab is selected
    • Instead of pulling state management out of
    TabBar, make it a controllable

    View Slide

  14. The old(ish) way:
    The Controllable mixin
    A Brief Aside
    About Mixins

    View Slide

  15. –Sebastian Markbåge, who knows what idiomatic React is
    “…mixins (are) an escape hatch to
    work around reusability limitations…
    Idiomatic React reusable code should
    primarily be implemented in terms of
    composition and not inheritance.”

    View Slide

  16. –Dan Abramov, while explaining what Sebastian Markbåge meant
    “Mixins are dead. Long live
    composition.”
    –Sebastian Markbåge, again
    “Another alternative to mixins…
    Higher Order Components.”

    View Slide

  17. A function that takes an existing component
    and returns another component that wraps it.
    Higher-Order
    Component

    View Slide

  18. The new way:
    The Controllable Higher-Order Component!
    Example: TabBar

    View Slide

  19. class TabBar extends React.Component {
    handleClick(event) {
    if (!this.props.onSelectedIndexChange) return;
    const el = event.target;
    const index = el.parentNode.children.indexOf(el);
    this.props.onSelectedIndexChange(index);
    }
    render() {
    const index = this.props.selectedIndex;
    return (

    Zero!
    One!
    Two!

    );
    }
    }
    TabBar.defaultProps = {selectedIndex: 0};
    TabBar = controllable(TabBar, ['selectedIndex']);

    View Slide

  20. Always use props!
    • No state in TabBar*
    • the controllable HOC handles the magic
    *
    Technically, the newly decorated TabBar does have state.
    The controllable can be thought of as providing an optional binding to a
    per-component state store.

    View Slide

  21. Controllable TabBar

    Controlled:
    Uncontrolled:
    Uncontrolled (with a default value):


    View Slide

  22. The future way?
    The Controllable Decorator!
    Example: TabBar

    View Slide

  23. – Sebastian McKenzie in the Babel.js 5.0 release post
    “Yehuda Katz' stage 1 decorators
    proposal allows you to elegantly
    compose property descriptors and
    metadata decoration.”

    View Slide

  24. JavaScript Decorators!
    • An expression that evaluates to a function
    • Easily annotate and modify classes and properties
    • Can act like a factory, taking additional arguments at
    design time
    • Currently a Stage 1 TC39 (ECMAScript) Proposal
    • Supported in Babel.js 5.0!
    (Python style. Basically lifted straight from Python.)

    View Slide

  25. @controllable(['selectedIndex'])
    class TabBar extends React.Component {
    static defaultProps = {selectedIndex: 0};
    static propTypes = {
    selectedIndex: PropTypes.number.isRequired,
    onSelectedIndexChange: PropTypes.func,
    };
    handleClick(event) {
    if (!this.props.onSelectedIndexChange) return;
    const el = event.target;
    const index = el.parentNode.children.indexOf(el);
    this.props.onSelectedIndexChange(index);
    }
    render() {
    const index = this.props.selectedIndex;
    return (

    Zero!
    One!
    Two!

    );
    }
    }

    View Slide

  26. HZDG.COM
    LETTERTWO
    ERIC ELDREDGE
    [email protected] HZDG
    PHOTO
    MISSING

    View Slide

  27. react-controllables
    https://github.com/matthewwithanm/react-controllables
    Another alternative to mixins…Higher Order
    https://twitter.com/sebmarkbage/status/565657028665016321
    JavaScript Decorators Proposal
    https://github.com/wycats/javascript-decorators
    Mixins Are Dead. Long Live Composition
    https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-
    Babel.js 5.0 Release Announcement
    http://babeljs.io/blog/2015/03/31/5.0.0/
    Props vs State
    https://speakerdeck.com/lettertwo/props-vs-state

    View Slide