higher-order components — ilya gelman
Post on 21-Jan-2017
106 Views
Preview:
TRANSCRIPT
Ilya Gelman
- Organizer of AngularJS-IL & ReactJS-Israel - Organizer of ReactNext 2016 - Author of The Complete Redux Book
Consultant @ 500Tech
function square(number) { return number * number; } var square = function (number) { return number * number;};
console.log(square);const square = (number) => number * number;array.map(square);
function square(number) { return number * number;} var square = function (number) { return number * number; };
console.log(square);const square = (number) => number * number;array.map(square);
function square(number) { return number * number;} var square = function (number) { return number * number; };
console.log(square); const square = (number) => number * number;array.map(square);
function square(number) { return number * number;} var square = function (number) { return number * number;};
console.log(square);const square = (number) => number * number; array.map(square);
class BaseComponent extends React.Component { ... }class InputComponent extends BaseComponent { ... }class Checkbox extends InputComponent { ... }
COMPOSITION VS. INHERITANCE
What things do What things are
Extend as you need Predict the future
Separated Tightly coupled
Startup Enterprise
class Checkbox extends React.Component { constructor() { Object.asign(this, { validate(...), enlargeOnMobile(), disableIf(...) }) }
}
const DropDown = ({ list = [] }) => ( <div className="dropdown"> <ul> { list.map((item) => <li>{ item }</li>) } </ul> </div>);
const DropDown = ({ list = [] }) => ( <div className="dropdown"> <ul> { list.map((item) => <li>{ item }</li>) } </ul> </div>);
const loadOptions = (Component) => class LoadOptions extends React.Component { constructor() { super(); this.state = { loaded: false, list: null } } componentDidMount() { API.fetchOptions().then( (list) => this.setState({ loaded: true, list }) ); } render() { return this.state.loaded && <Component list={ this.state.list }/>; } };
const loadOptions = (Component) => class LoadOptions extends React.Component { constructor() { super(); this.state = { loaded: false, list: null } } componentDidMount() { API.fetchOptions().then( (list) => this.setState({ loaded: true, list }) ); } render() { return this.state.loaded && <Component list={ this.state.list }/>; } };
const loadOptions = (Component) => class LoadOptions extends React.Component { constructor() { super(); this.state = { loaded: false, list: null } } componentDidMount() { API.fetchOptions().then( (list) => this.setState({ loaded: true, list }) ); } render() { return this.state.loaded && <Component list={ this.state.list }/>; } };
const loadOptions = (Component) => class LoadOptions extends React.Component { constructor() { super(); this.state = { loaded: false, list: null } } componentDidMount() { API.fetchOptions().then( (list) => this.setState({ loaded: true, list }) ); } render() { return this.state.loaded && <Component list={ this.state.list }/>; } };
const loadOptions = (Component) => class LoadOptions extends React.Component { constructor() { super(); this.state = { loaded: false, list: null } } componentDidMount() { API.fetchOptions().then( (list) => this.setState({ loaded: true, list }) ); } render() { return this.state.loaded && <Component list={ this.state.list }/>; } };
const loadOptions = (Component) => class LoadOptions ...
const loadOptions = (Component) => { class LoadOptions ...
return React.createElement(LoadOptions); }
const DropDown = (...) => (...); const LazyDropDown = loadOptions(DropDown); const App = () => ( <div> <LazyDropDown /> </div>);
const DropDown = (...) => (...);
const App = () => ( <div> { logProps(<DropDown list={ … } />) } </div>);
import { withState } from 'recompose'; const DropDown = ({ list, visible, setVisibility }) => ( <div className="dropdown" onClick={ () => setVisibility(visible => !visible) }> { visible && <ul>/* { ... } */</ul> } </div>); export default withState( 'visible', // value on state 'setVisibility', // callback to change the state false // initial value)(DropDown);
import { withState } from 'recompose'; const DropDown = ({ list, visible, setVisibility }) => ( <div className="dropdown" onClick={ () => setVisibility(visible => !visible) }> { visible && <ul>/* { ... } */</ul> } </div>); export default withState( 'visible', // value on state 'setVisibility', // callback to change the state false // initial value)(DropDown);
import { withState } from 'recompose';const DropDown = ({ list, visible, setVisibility }) => ( <div className="dropdown" onClick={ () => setVisibility(visible => !visible) }> { visible && <ul>/* { ... } */</ul> } </div>); export default withState( 'visible', // value on state 'setVisibility', // callback to change the state false // initial value)(DropDown);
import { withState } from 'recompose';const DropDown = ({ list, visible, setVisibility }) => ( <div className="dropdown" onClick={ () => setVisibility(visible => !visible) }> { visible && <ul>/* { ... } */</ul> } </div>); export default withState( 'visible', // value on state 'setVisibility', // callback to change the state false // initial value)(DropDown);
import { withState, mapProps, pure } from 'recompose';
...
withState(..., mapProps(..., pure(MyComponent)));
function compose(...fns) { const lastFn = fns[fns.length - 1] const restFns = fns.slice(0, -1)
return (target) => restFns.reduceRight( (composed, f) => f(composed), lastFn(target) )
}
function compose(...fns) { const lastFn = fns[fns.length - 1] const restFns = fns.slice(0, -1)
return (target) => restFns.reduceRight( (composed, f) => f(composed), lastFn(target) )
}
function compose(...fns) { const lastFn = fns[fns.length - 1] const restFns = fns.slice(0, -1)
return (target) => restFns.reduceRight( (composed, f) => f(composed), lastFn(target) )
}
function compose(...fns) { const lastFn = fns[fns.length - 1] const restFns = fns.slice(0, -1)
return (target) => restFns.reduceRight( (composed, f) => f(composed), lastFn(target) )
}
– Prefer composition over inheritance
– Use stateless components
– npm install recompose
– Don’t miss ReactNext 2016
Read our blog:http://blog.500tech.com
Ilya Gelmanilya@500tech.com
top related