Skip to content

Instantly share code, notes, and snippets.

@gsrai
Last active July 20, 2018 16:58
Show Gist options
  • Save gsrai/2e19a1ad745ab0f882e120761b7b2652 to your computer and use it in GitHub Desktop.
Save gsrai/2e19a1ad745ab0f882e120761b7b2652 to your computer and use it in GitHub Desktop.

React Casts

Keywords: State tree, Component Tree

#1 Higher Order Components

Function that takes a component as a parameter and returns an augmented component. Can inspect and change passed props and hijack the render entirely

#2 Function as Child Components

A Parent component accepts children as a function instead of a node. <Parent> { param => () } </Parent> vs <Parent><Child /></Parent> This allows the parent component to do some internal processing and inject props into a supplied child function.

#3 Children API

this.props.children can be anything (opaque data structure), empty, single element, array of elements etc. React.Children API has a few utility functions: .only(this.props.children) -> only renders one element child .cound(this.props.children) -> show a count of how many children .map(this.props.children, func) -> map over children applying the passed in function .toArray(this.props.children) -> convert children of Node type to Array

#4 React Context

Alternative to passing props down the component tree, effectively globally accessible props. Should be used sparingly but is useful for localisation and themeing.

old API: in the root or grandparent component declare ChildContextTypes proptype object and a getChildContext Hook (producer): App.childContextTypes = { locale: Proptypes.object }

getChildContext() {
  return { locale: locales.en }
}

then in the grandchild component (consumer): SomeChild.contextTypes = { locale: Proptypes.object } in the render method:

render() {
  const { locale } = this.context
}

however if any middle child implements ShouldComponentUpdate then the context breaks, to solve this pass the context props as references updating the object being referenced and using forceComponentUpdate Using higherorder comps we can abstract the old experimental API

#6 Redux Middleware

custom function that sits inbetween the dispatcher and reducers, able to do some processing before an action reaches the reducer. the middleware curried function accepts a next param which if not called will stop the action propagating to the reducers.

#8 Redux Selectors

convenience function that allow lookup and retrieval of data from the redux store the mapstatetoprops fuction should only map state to props and not have any logic in there (such as build new data from store data). selectors can be declared inside the reducer and used when connecting the store to the component, for reusability Selectors can be created when reducers have relationships, by creating selector the accepts in the entire state, it can take data from multiple reducers and combine them to make new data this is an alternative to importing two reducers when connecting a component for performance you should memoize your state, a common library to use is reselect

#9 Immutable javascript

array and object operators ins es5 can be destructive, using the new spread operator (shallow copy) and map filter reduce methods we can operate on arrays and objects in an immutable fashion.

#11 React Recompose

React recompose is a library that allows us to use functional components where you need class components. Class components extend React.Component which provides lifecycle hooks and internal state, as well as event handler methods. with recompose you can use helpers to compose functions and wrap your functional components.

// FunctionAsChildComponentExample
import React from 'react'
const Parent = (props) => {
return (
<div>
{ props.children("some injected prop") }
</div>
)
}
const App = (props) => {
return (
<Parent>
{
param => <div>{param}</div>
}
</Parent>
)
}
// HigherOrderComponentExample
import React, { Component } from 'react'
// https://gist.github.com/sebmarkbage/ef0bf1f338a7182b6775
// will augment component to include a loading wheel
// curried Higher order function
const LoaderHOC = (propName) => (WrappedComponent) => {
return class LoaderHOC extends Component {
isEmpty(prop) {
return (
prop === null ||
prop === undefined ||
(prop.hasOwnProperty('length') && prop.length === 0) ||
(prop.constructor === Object && Object.keys(prop).length === 0)
)
}
render() {
return this.isEmpty(this.props[propName])
? <div className='loader'></div>
: <WrappedComponent {...this.props} />
}
}
}
export default LoaderHOC
// use:
LoaderHOC('contacts')(ContactsApp)
// HOC is stateful with lifecycle hooks passing in data as props to functional presetational component
const Enhance = ComposedComponent => class extends Component {
constructor() {
this.state = { data: null }
}
componentDidMount() {
this.setState({ data: 'Foo' })
}
render() {
return <ComposedComponent {...this.props} data={this.state.data} />
}
}
const MyComponent = (props) => {
if (!props.data) return <div>Waiting...</div>
return <div>{props.data}</div>
}
export default Enhance(MyComponent)
// ReduxMiddlewareExample
import { createStore, applyMiddleware } from 'redux'
import reducer from './reducers'
// curried function takes store and action, allows asynchronous chaining with next callback
const loggerMiddleware = store => next => action => {
console.log('dispatching action: ', action)
next(action)
}
const store = createStore(
reducer,
applyMiddleware(loggerMiddleware)
)
// ContextHigherOrderComponentExample
import React, { Component, Proptypes } from 'react'
const WithLocaleHOC = (WrappedComponent) => {
return class WithLocale extends Component {
static contextTypes = {
locale: Proptypes.object
}
render() {
const { locale } = this.context
return <WrappedComponent {...this.props} />
}
}
}
export default WithLocaleHOC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment