React, Redux, Apollo and friends..

πŸš€, πŸ“, β˜€οΈ, & πŸ‘¨β€πŸ‘§β€πŸ‘¦

πŸ₯‡ Best practices and such πŸ₯‡

Dave Anderson - Stride

πŸ“£ Overview πŸ“£

  • High-level thoughts and best practices πŸ€”
  • Feel free to ask questions ⁉️
  • Some solid references for reading, but most examples will be live-googled if needed πŸƒ

🌈 Pure Functions 🌈

  • Simple: Input -> Output
  • No side effects
  • No dependency to outside state
  • Easy to test
  • Easy to reason about
    • Name it well
    • Keep it small
    • Decompose complex operations into more, easily testable pure functions

πŸš€ React πŸš€

  • Organizing
  • Components
  • Containers
  • Pages
  • Testing

React - Organization

  • components/
    • MyComponent.js
    • AnotherComponent/
      • index.js <- just a component!
      • styles.js
  • containers/
    • MyContainer/
      • index.js <- connect redux & apollo
      • styles.js
      • component.js <- just a component!
  • pages/
    • similar to components and containers..

React Components

  • Prefer functional stateless components
  • Pure! View only! Easy to test!
  • Use class components only when React lifecycle hooks are needed
  • Local state - think hard if it's needed!
    • Harder to reason about and test!
  • Decompose functionality into more components or functions in utility modules

Containers

  • Inject Redux state and Apollo data into components
  • Test view separately as a pure function of props
  • Test mapping as pure functions separately too
    • mapStateToProps
    • mapDispatchToProps
    • mapResultsToProps

Pages

  • Basically components or containers but..
  • Used to organize things into page/screen based views
  • Useful to separate into its own folder for organization purposes

Testing

  • Where to keep them? Mirror folder structure under `tests` or keep alongside tested unit of code?
  • Make Unit tests! Lots of them!
    • Cheap: 1600+ running in < 3 seconds
  • Enzyme
    • Prefer shallow over mount
    • Use mount for lifecycle events or deeply nested components
    • Avoid render when possible (slow)
  • Ensure small components with output as a pure function of props for manageable testing scope
  • Use dependency injection of props rather than globals such as `window` when possible

πŸ“ Redux πŸ“

  • State, reducers, selectors, actions
  • Structure
  • Speed bumps

Redux - State, etc.

  • Store minimalΒ state required to render app
    • Not state if it can be derived from another value
  • Use selectors to abstract containers from shape of state
    • Selectors for simple values from state
    • Selectors for computed values from state
    • Pure functions! Test them!
  • Redux-actions to help with boilerplate for reducers and actions

Redux - Structure

  • store
    • user
      • reducers.js
      • actions.js
      • selectors.js
    • anotherStore
      • ...

Redux - Speed bumps

  • Avoid connecting leaf-level components to store!
    • Harder to reason about - prefer passing down props
  • Serializing state - local storage or server session
    • OR just use Apollo mutations to persist on the server!
  • Normalizing API data - painful - redundant with Apollo
  • Mixing Apollo cache data and redux state - not recommended
  • Most redux code for managing API connections is made redundant by Apollo

β˜€οΈ Apollo β˜€οΈ

  • Queries
  • Mutations
  • Testing w/ Mock API

Apollo - Queries

  • Similar to redux, use `grapqhl()` per `gql` query to connect component to Apollo data/cache
    • Injects `data` property to component
    • Apollo handles logic for managing loading and error states
  • Structure queries into fragments to understand context in which data is being used and make them more easy to reason about
  • Use functional `compose` to organize Higher Order Components
  • Avoid using lower level API to query the cache if possible!
  • Make changes to schema to serve the client - quick feedback loops

Apollo - Mutations

  • Graphql Mutations are used to change data on the server
  • Also connected to component via `graphql()`
    • Injects `mutation` property to component
    • Call function (Promise) with arguments to resolve the change to the server
    • Use name and alias options to differentiate when multiple `mutations` are present.
  • Queries won't reflect changed data automatically!
    • Refetch queries to reflect changed data
    • Use optimistic mutation to immediately make changes to local Apollo cache without server response

Apollo - Mock API & Testing

  • Graphql endpoints have a statically typed schema
  • Schema can be generated through introspection on the endpoint and used by tools for things like
    • API mocking
    • Contract testing

⁉️ Questions ⁉️

  • πŸš€?
  • πŸ“?
  • β˜€οΈ?

References

  • 9 Things To Learn in React..
    https://camjackson.net/post/9-things-every-reactjs-beginner-should-know
  • Functional stateless components in React
    https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc
  • Organizing React and Redux:
    https://medium.com/bumpers/isnt-our-code-just-the-best-f028a78f33a9
  • Reducing Redux code with Apollo:
    https://dev-blog.apollodata.com/reducing-our-redux-code-with-react-apollo-5091b9de9c2a

More references...

  • Redux Selectors:
    https://www.saltycrane.com/blog/2017/05/what-are-redux-selectors-why-use-them/
  • Organizing State:
    https://redux.js.org/docs/faq/OrganizingState.html
  • Graphql Cheatsheet:
    https://wehavefaces.net/graphql-shorthand-notation-cheatsheet-17cd715861b6
  • Apollo Queries:
    https://www.apollographql.com/docs/react/basics/queries.html
  • Apollo v1 Fragments & Pokemon tutorial:
    https://www.learnapollo.com/tutorial-react/react-04/
  • Apollo Mutations:
    https://www.apollographql.com/docs/react/basics/mutations.html

React, Redux, Apollo and friends

By dvndrsn

React, Redux, Apollo and friends

Best practices for using these frameworks together

  • 696