advanced react
TRANSCRIPT
Topics• YAGNI
• Redux • React Router • Presentational and Container Components
• Web Components in React
• Higher Order Components
• Live Code Example
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• 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
• 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/