KEMBAR78
Advanced React | PDF
by Mike Wilcox, November 2017
Advanced React
Topics
• YAGNI
• Redux
• React Router
• Presentational and Container Components
• Web Components in React
• Higher Order Components
• Live Code Example
YAGNI
Do You Need Redux?
• Boot from local storage
• Store UI state on server
• Bug reports
• Undo
• Macros / TDD.
• Client side reports or browser extensions
• Swappable UIs
https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367
You might need Redux to:
Redux
The boilerplate to implement Redux is
enormous. If a Redux-specific feature is not
mandated by management, eschew it for
React state, a pub/sub system, or one of
the many Flux alternatives.
I didn’t even mention Redux Forms…
Over-Engineering
Presentational and Container Components
• Containers: Manage data
• Presentationals: Manage DOM
• If you’re using Redux, a Container doesn’t make any sense
• Data fetching should happen in a service, not a component
• A rarely-used pattern in an app
• Better pattern for a library
• More important is determining which component manages
state
• Technically, a Container could manage state too, but then it becomes tightly
coupled
• Example
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
React Router
• Now on version 4.x, and the seem to have gotten it right
• Not terribly difficult to use
• Relatively bug-free if used as intended
Curated by React Training, a company that sells training seminars
Pros
Cons
• It took them 4 versions to get it right
• The redux plugin has been in perpetual alpha stage
• The company really pushes their wares
React Router
You don’t have to use React Router
const routes = [
{ path: '/', action: () => <HomePage /> },
{ path: '/tasks', action: () => <TaskList /> },
{ path: '/tasks/:id', action: () => <TaskDetails /> }
];
function renderComponent(component) {
ReactDOM.render(component, container);
}
function render(location) {
router.resolve(routes, location)
.then(renderComponent)
.catch(error => router.resolve(routes, { ...location, error })
.then(renderComponent));
}
For complete code, see reference: https://medium.freecodecamp.org/you-might-not-need-react-router-38673620f3d
Web Components
Web Components
• The React team, while no longer openly hostile, still do not embrace WCs.
• Most events do not work, and you can’t pass in complex data
• Forced to rely upon refs for everything
• Many of the reasons to use JSX are mitigated
• Which means a lot of redundant boiler plate
Web Components
@clubajax/react-web-component
<WebComponent
component="drop-down"
label="Model"
placeholder="Choose Model"
data={this.state.models}
value={this.state.model}
onChange={this.onChooseModel}
/>
The React Web Component makes for a smooth transition between
React and Web Components by allowing to pass objects as
attributes, and listen to custom events.
HOFs/HOCs
HOFs
• Built-in HOFs: map, filter, reduce, etc.
• HOFs do not mutate the variable they are called on
• Ideally, HOFs accept functions with identical signatures
• Composition FTW
Higher-Order Functions
A higher-order function does at least one of the following:
takes one or more functions as arguments (i.e., procedural parameters)
returns a function as its result.
HOFs
const upperCase = (arr) => arr.map(str => str.toUpperCase());
const trim = (arr) => arr.map(str => str.trim());
const dashify = (arr) => arr.map(str => str.replace(/s/g, '-'));
const compose = (...fns) => {
return (...args) => {
return fns.reduce((a, b) => {
return b(a);
}, ...args);
}
};
hof = compose(trim, upperCase, dashify);
hof([' my house ', ' in the middle ', ' of our street ‘]);
// ['MY-HOUSE', 'IN-THE-MIDDLE', 'OF-OUR-STREET']
HOCs
• An advanced technique in React for reusing component logic
• A pattern that emerges from React’s compositional nature
• An HOC is a pure function with zero side-effects
Higher Order Components
A higher-order component is a function that takes a component and returns a new
component.
https://reactjs.org/docs/higher-order-components.html
HOCs
https://reactjs.org/docs/higher-order-components.html
function logProps(WrappedComponent) {
return class extends React.Component {
componentWillReceiveProps(nextProps) {
console.log('Current props: ', this.props);
console.log('Next props: ', nextProps);
}
render() {
// Wraps the input component in a container, without mutating it.
return <WrappedComponent {...this.props} />;
}
}
}
Wrapped Component
class LogComponent extends React.Component {
componentWillReceiveProps (nextProps) {
console.log('Current props: ', this.props);
console.log('Next props: ', nextProps);
}
render () {
return <this.props.component {...this.props} />;
}
}
<LogComponent
component={MyComponent}
title="Foo"
onChange={this.onChange}
/>
A wrapped component is very similar to an HOC. It takes a component as a prop.
HOCs
• Static Methods Must Be Copied Over
• Refs Aren’t Passed Through
• Namespace collisions
• Performance issues
• It is very difficult to make them composable
• Only worthwhile if HOC are truly being reused
• Is the Component a class, a function or an object?
Cons
Render Prop
class Mouse extends React.Component {
handleMouseMove = (e) => {
this.setState({ x: e.clientX, y: e.clientY });
}
render() {
return (
<div onMouseMove={this.handleMouseMove}>
{this.props.render(this.state)}
</div>
const App = React.createClass({
render() {
return (
<div>
<Mouse render={({ x, y }) => (
<h1>The mouse position is ({x}, {y})</h1>
)}/>
</div>
A render prop is a function prop that a component uses to know what to render.
https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce
Live Code Example
https://github.com/clubajax/advanced-react/
Advanced React

Advanced React

  • 2.
    by Mike Wilcox,November 2017 Advanced React
  • 3.
    Topics • YAGNI • Redux •React Router • Presentational and Container Components • Web Components in React • Higher Order Components • Live Code Example
  • 4.
  • 5.
    Do You NeedRedux? • Boot from local storage • Store UI state on server • Bug reports • Undo • Macros / TDD. • Client side reports or browser extensions • Swappable UIs https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367 You might need Redux to:
  • 6.
    Redux The boilerplate toimplement Redux is enormous. If a Redux-specific feature is not mandated by management, eschew it for React state, a pub/sub system, or one of the many Flux alternatives. I didn’t even mention Redux Forms… Over-Engineering
  • 7.
    Presentational and ContainerComponents • Containers: Manage data • Presentationals: Manage DOM • If you’re using Redux, a Container doesn’t make any sense • Data fetching should happen in a service, not a component • A rarely-used pattern in an app • Better pattern for a library • More important is determining which component manages state • Technically, a Container could manage state too, but then it becomes tightly coupled • Example https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
  • 8.
    React Router • Nowon version 4.x, and the seem to have gotten it right • Not terribly difficult to use • Relatively bug-free if used as intended Curated by React Training, a company that sells training seminars Pros Cons • It took them 4 versions to get it right • The redux plugin has been in perpetual alpha stage • The company really pushes their wares
  • 9.
    React Router You don’thave to use React Router const routes = [ { path: '/', action: () => <HomePage /> }, { path: '/tasks', action: () => <TaskList /> }, { path: '/tasks/:id', action: () => <TaskDetails /> } ]; function renderComponent(component) { ReactDOM.render(component, container); } function render(location) { router.resolve(routes, location) .then(renderComponent) .catch(error => router.resolve(routes, { ...location, error }) .then(renderComponent)); } For complete code, see reference: https://medium.freecodecamp.org/you-might-not-need-react-router-38673620f3d
  • 10.
  • 11.
    Web Components • TheReact team, while no longer openly hostile, still do not embrace WCs. • Most events do not work, and you can’t pass in complex data • Forced to rely upon refs for everything • Many of the reasons to use JSX are mitigated • Which means a lot of redundant boiler plate
  • 12.
    Web Components @clubajax/react-web-component <WebComponent component="drop-down" label="Model" placeholder="Choose Model" data={this.state.models} value={this.state.model} onChange={this.onChooseModel} /> TheReact Web Component makes for a smooth transition between React and Web Components by allowing to pass objects as attributes, and listen to custom events.
  • 13.
  • 14.
    HOFs • Built-in HOFs:map, filter, reduce, etc. • HOFs do not mutate the variable they are called on • Ideally, HOFs accept functions with identical signatures • Composition FTW Higher-Order Functions A higher-order function does at least one of the following: takes one or more functions as arguments (i.e., procedural parameters) returns a function as its result.
  • 15.
    HOFs const upperCase =(arr) => arr.map(str => str.toUpperCase()); const trim = (arr) => arr.map(str => str.trim()); const dashify = (arr) => arr.map(str => str.replace(/s/g, '-')); const compose = (...fns) => { return (...args) => { return fns.reduce((a, b) => { return b(a); }, ...args); } }; hof = compose(trim, upperCase, dashify); hof([' my house ', ' in the middle ', ' of our street ‘]); // ['MY-HOUSE', 'IN-THE-MIDDLE', 'OF-OUR-STREET']
  • 16.
    HOCs • An advancedtechnique in React for reusing component logic • A pattern that emerges from React’s compositional nature • An HOC is a pure function with zero side-effects Higher Order Components A higher-order component is a function that takes a component and returns a new component. https://reactjs.org/docs/higher-order-components.html
  • 17.
    HOCs https://reactjs.org/docs/higher-order-components.html function logProps(WrappedComponent) { returnclass extends React.Component { componentWillReceiveProps(nextProps) { console.log('Current props: ', this.props); console.log('Next props: ', nextProps); } render() { // Wraps the input component in a container, without mutating it. return <WrappedComponent {...this.props} />; } } }
  • 18.
    Wrapped Component class LogComponentextends React.Component { componentWillReceiveProps (nextProps) { console.log('Current props: ', this.props); console.log('Next props: ', nextProps); } render () { return <this.props.component {...this.props} />; } } <LogComponent component={MyComponent} title="Foo" onChange={this.onChange} /> A wrapped component is very similar to an HOC. It takes a component as a prop.
  • 19.
    HOCs • Static MethodsMust Be Copied Over • Refs Aren’t Passed Through • Namespace collisions • Performance issues • It is very difficult to make them composable • Only worthwhile if HOC are truly being reused • Is the Component a class, a function or an object? Cons
  • 20.
    Render Prop class Mouseextends React.Component { handleMouseMove = (e) => { this.setState({ x: e.clientX, y: e.clientY }); } render() { return ( <div onMouseMove={this.handleMouseMove}> {this.props.render(this.state)} </div> const App = React.createClass({ render() { return ( <div> <Mouse render={({ x, y }) => ( <h1>The mouse position is ({x}, {y})</h1> )}/> </div> A render prop is a function prop that a component uses to know what to render. https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce
  • 21.