Skip to content

Instantly share code, notes, and snippets.

@tf
Last active January 26, 2019 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tf/2dc63e72faf72f4cc44ebf261a3ddcc8 to your computer and use it in GitHub Desktop.
Save tf/2dc63e72faf72f4cc44ebf261a3ddcc8 to your computer and use it in GitHub Desktop.

Concurrent React, Redux and State Management

Concurrent React

Time Slicing

  • Prevent blocking
*  setState
*  start render
*  render yield
|
|  *  some other event handler
|
*  render continue
*  render yield
|
|  *  some other event handler
|
*  render continue
*  render finish
  • Prioritized reconciling
*  (low priority event)
|
*  setState
*  start render
*  render yield
|
|  *  (high priority event)
|  |
|  *  setState
|  *  render start
|  |
|  *  finish render
|
*  re-apply state change
*  render

Suspense

  • Throwing Promises

  • Placeholders

  • maxDuration

*  (event)
|
*  setState
*  start render
*  render throw promise
.
.
.  *  (event)
.  |
.  *  setState
.  *  render start
.  *  finish render
.
.
.
.
*  promise resolve
*  re-aplly state change
*  render

Consequences

  • React is in charge of state

  • Ensures consistent state for tree across time slices (no "tearing")

  • "Work in progress" state

Redux

  • v5: Strore via Context

  • v6: State (and Store) via Context

  • Push vs Pull

                                    |   REDUX STORE
                                    |
*      (low priority event)         |   { users: [] }
|                                   |
*      dispatch                     |
*      store change                 |   { users: [a,b,c] }
*      Provider#setState            |
*      render start                 |
*      render yield                 |
|                                   |
|  *     (high priority event)      |
|  |                                |
|  *     dispatch                   |
|  *     store change               |  { expanded: true, users: [a,b,c] }
|  *     Provider#setState          |
|  *     render start               |
|  |                                |
x  |   cancel render                |
   |                                |
   *     finish render              |

Component State > Global State

Caching External Data

  • Prevent re-fetching data

  • Take advantage of concurrent rendering mode

  • Prevent tearing

Component State?

  • Data lost on unmount

  • Does not work with suspense

Global Singleton?

  • Risk of tearing

Context.write

reactjs/rfcs#89

React managed state outside the component tree

const Context = React.createContext(defaultValue);

function Component() {
  return (
    <Context.Consumer>
      {value => /* render something ... */} 
    </Context.Consumer>
  );
}
const Context = React.createContext(initialValue, contextDidUpdate);

Context.write(newValue);

Context.write(prevValue => newValue);
const Store = React.createContext(initialState);

export function dispatch(action) {
  Store.write(state => reducer(state, action));
}

export function useStore() {
  return useContext(Store);
}
                                    | Context
                                    |
*      (low priority event)         |    * { users: [] }
|                                   |    |
*      dispatch                     |    |\
*      Context.write                |    * \  { users: [a,b,c] }
*      render start                 |    |  \
*      render yield                 |    |  |
|                                   |    |  |
|  *     (high priority event)      |    |  |
|  |                                |    |  |
|  *     dispatch                   |    |  |
|  *     Context.write              |    |  * { expanded: true, users: [] }
|  *     render start               |    |  /
|  *     finish render              |    | /
*                                   |    |/
*      re-apply state changes       |    *  { expanded: true, users: [a,b,c] }
*      render

Dependency Injection/Testing

<Store.Provider value={...}>
  <TestedComponent />
</Store.Provider>

Let Others Take Care of It

  • React Apollo

  • Unstated

  • Relay?

Thanks!

github.com/tf @tfischbach

www.codevise.de

References

https://www.youtube.com/watch?v=nLF0n9SACd4

https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/

reduxjs/react-redux#890

reduxjs/react-redux#1000

reactjs/rfcs#89

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