advanced react

22

Upload: mike-wilcox

Post on 21-Jan-2018

69 views

Category:

Technology


0 download

TRANSCRIPT

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:

ReduxThe 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

• Examplehttps://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 seminarsPros

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 RouterYou 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.

HOFsconst 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 ComponentsA 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 Propclass 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/