Slide 1

Slide 1 text

higher order components In react 2016

Slide 2

Slide 2 text

Senior engineer @ . Italian react & angular communities Matteo Ronchi @cef62 github/cef62

Slide 3

Slide 3 text

From Documents to components

Slide 4

Slide 4 text

Title Text

Some text about something

HyperText Markup Language

Slide 5

Slide 5 text

$(document).ready(() => { $.ajax(‘my-url.php’) .done((data) => { $(‘#my-title’).text(data.title) $(‘#my-contents’).text(data.contents) }) }) jQuery

Slide 6

Slide 6 text

angular.module(‘app’, []).directive(‘myPage’, function($http) { return { scope: { myUrl: ‘@’} template: `<div> <h1>{{myTitle}}</h1> <p>{{myContents}}</p> </div>` link: function(scope) { $http.get(scope.myUrl).success((data) => { scope.myTitle = data.title scope.myContents = data.contents }) } } }) AngularJS

Slide 7

Slide 7 text

class App extends React.Component { componentWillMount() { axios.get(this.props.myUrl).then(({ title, contents }) => { this.setState({ title, contents }) }) } render() { return ( <div> <h1>{this.state.title}</h1> <p>{this.state.contents}</p> </div> ) } } ReactDOM.render(<App myUrl=“my-url.php” />, document.getElementById(‘root’)) React

Slide 8

Slide 8 text

react angular 2 polymer all modern frameworks are component oriented

Slide 9

Slide 9 text

Everything is a Component an application is a tree of components

Slide 10

Slide 10 text

Components are • Composable • Encapsulated • Reusable • Easy to design

Slide 11

Slide 11 text

presentational components small, reusable, pure functions, easy to test

Slide 12

Slide 12 text

const Label = (props) =>

{props.children}

const Icon = (props) => { return ( {props.label} ) } const App = () =>
Some label
Stateless Functional Components

Slide 13

Slide 13 text

Component lifecycle

Slide 14

Slide 14 text

class MyComponent extends React.Component { // Component Initialization constructor(props) {} // component ready to be mounted componentWillMount() {} // Props have changed componentWillReceiveProps(nextProps) {} // prevent rendering if not required shouldComponentUpdate(nextProps, nextState) {} // Prepare before rendering componentWillUpdate(nextProps, nextState) {} } Component Lifecycle

Slide 15

Slide 15 text

class MyComponent extends React.Component { // create/update the component render() {} // Component DOM it’s been created componentDidMount() {} // Component DOM it’s been updated componentDidUpdate(prevProps, prevState) {} // cleanup before component destruction componentWillUnmount() {} } Component Lifecycle

Slide 16

Slide 16 text

Container Components Context-aware, stateful, dynamic, powerful

Slide 17

Slide 17 text

class Toggle extends React.Component { constructor(props) { super(props) this.state = { enabled: false } this.toggle = this.toggle.bind(this) } toggle() { this.setState({ enabled: !this.state.enabled }) } render() { const cls = this.state.enabled ?'btn-success':'btn-danger' return ( {this.props.label} ) } } Stateful Components

Slide 18

Slide 18 text

REDUCE code boilerplAte

Slide 19

Slide 19 text

class Box extends React.Component { constructor(props) { this.state = { info: {} } } componentWillMount() { axios.get(this.props.url).then( ({ data }) => this.setState({ info: data }) ) } render() { return
{this.state.info.text}
} } class User extends React.Component { constructor(props) { this.state = { user: {} } } componentWillMount() { axios.get(this.props.url).then( ({ data }) => this.setState({ user: data }) ) } render() { return
{this.state.user.name}
} } Components Share Functionalities

Slide 20

Slide 20 text

REACT mixins

Slide 21

Slide 21 text

const LoadDataMixin = { loadData(url, targetField) { axios.get(url).then( ({ data }) => this.setState({ [targetField]: data }) ) } } React Mixins

Slide 22

Slide 22 text

const BoxInfo = React.createClass({ mixins: [LoadDataMixin], getInitialState() { return { info: {} } }, componentWillMount() { this.loadData(this.props.url, 'info') }, render() { return
{this.state.info.text}
} }) const UserPanel = React.createClass({ mixins: [LoadDataMixin], getInitialState() { return { user: {} } }, componentWillMount() { this.loadData(this.props.url, 'user') }, render() { return
{this.state.user.name}
} }) React Mixins

Slide 23

Slide 23 text

higher order functions

Slide 24

Slide 24 text

— Marijn Haverbeke ( eloquent javascript ) Higher-order functions allow us to abstract over actions, not just values.

Slide 25

Slide 25 text

function applyVat(vat) { return (value) => ((vat + 100) / 100) * value } const applyVat22 = applyVat(22) console.log(applyVat22(100)) // print -> 122 function maybe(condition, action) { if (condition) { action() } } const action = (msg) => () => console.log(msg) maybe(true, action(`It works!`)) maybe(false, action(`Doesn't work!`)) // print -> It works! HoF

Slide 26

Slide 26 text

From Higher order functions ( TO ) Higher order components

Slide 27

Slide 27 text

const Wrapped = () =>

Wrapped Comp

const wrapper = (Comp) => () => { return
} const FinalComponent = wrapper(Wrapped) const App = () => { return (
) } Simple HoC

Slide 28

Slide 28 text

const loadData = (Component) => { return class LoadDataWrapper extends React.Component { constructor(props) { this.state = { data: {} } } componentWillMount() { axios.get(this.props.url).then( ({ data }) => this.setState({ data }) ) } render() { const props = Object.assign({}, this.props, this.state) return React.createElement(Component, props) } } } const Box = loadData((props) =>
{props.data.text}
) const User = loadData((props) =>
{props.data.name}
) Reduce Duplication of Code

Slide 29

Slide 29 text

@loadData class Box extends React.Component { render() { return
{this.props.data.text}
} } @loadData class User extends React.Component { render() { return
{this.props.data.name}
} } // See https://github.com/wycats/javascript-decorators Decorator Proposal

Slide 30

Slide 30 text

HoC vs Mixins - Declarative - Customizable - Easy to read - Enforce composition Imperative - Favors inheritance - Hard to read - Method names collision - Access component state -

Slide 31

Slide 31 text

HoC - Best Practices • Expose wrapped component • Pass props to wrapped component • Expose statics methods and props from wrapped component

Slide 32

Slide 32 text

code See online

Slide 33

Slide 33 text

thanks ! @CEF62