Skip to content

Instantly share code, notes, and snippets.

@iegik
Last active January 29, 2021 17:41
Show Gist options
  • Save iegik/4dd187602f5b288ff042430ac08783f2 to your computer and use it in GitHub Desktop.
Save iegik/4dd187602f5b288ff042430ac08783f2 to your computer and use it in GitHub Desktop.

Presentational and Container Components

Dumb (stateless) and Smart components

Dumb:

import React from 'react';
export default (props = {}) => (
    <View/>
)

Smart

export default class extends Component {
  state = {}
  shouldComponentUpdate(nextProps, nextState){
    if (this.props.shuldChildUpdate === nextProps.shuldChildUpdate) {
        return false;
    }
    return true;
  }
  render = () => {
    const { children } = this.props;
    return (
      <div>{children}</div>
    )
  }
}

componentShouldUpdate working as expected while in reality asking how to have the child update when the parent does not

Pure

export default class extends PureComponent {
  state = {}
  // smart shouldComponentUpdate included
  render = () => {
    const { immutable } = this.state;
    return (
      <div>{immutable}</div>
    )
  }
}

Lifecycle

export default class extends Component {
  state = {}
  constructor()
  // depricated componentWillMount = () => {}
  // depricated componentWillReceiveProps = (nextProps) => {}
  static getDerivedStateFromProps = (props, state) => {}
  shouldComponentUpdate = (nextProps, nextState) => {}
  // depricated componentWillUpdate = (nextProps, nextState) => {}
  render = () => {}
  componentDidMount = () => {}
  componentDidUpdate = (prevProps, prevState) => {}
  componentWillUnmount = () => {}
  componentDidCatch = (error, info) => {}
}
  • Wrapping components should not use shouldComponentUpdate
  • Most of the time, you can use React.PureComponent instead of writing your own shouldComponentUpdate
  • Avoid getDerivedStateFromProps in almost all cases (reference)
shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false
}

This pattern is common enough that React provides a helper to use this logic - just inherit from React.PureComponent

How to read an ID from React Router in mapStateToProps()?

See - https://twitter.com/dan_abramov/status/719971882280361985?lang=en

const makeMapStateToProps = (initialState, initialProps) => (state) => ({});

connect(makeMapStateToProps)(Component)

React.memo

const memo = (fn, areEqual) => class extends React.Component {
  shouldComponentUpdate = (nextProps) => {
    if (areEqual) {
      return !areEqual(this.props, nextProps);
    }

    return true;
  }

  render = () => fn(this.props);
};

Usage:

memo(ComponentWithoutProps, () => true)

Redux

import {selectValueForProp} from './selectors'
import {action} from './action'
export const mapStateToProps = state => ({
  prop: selectValueForProp(state),
});
export const mapDispatchToProps = dispatch => ({
  onChange: (value) => {
      value && dispatch(action(value)) // Command pattern? `value && dispatch(command(value).execute())`
  },
  dispatch,
});
export const mergeProps = (stateProps, dispatchProps) => ({
  toggle: () => stateProps.on ? dispatchProps.onEnable() : dispatchProps.onDisable(),
});
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component)

Redux Saga

  • mapStateToProps = state => ({}) -
  • mapDispatchToProps = dispatch => ({}) -

connect(mapStateToProps, mapDispatchToProps)(Component)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment