Manage state

of

A Large React App

by @JSDude005


www.thatJSDude.com

Who is

JS Dude?

  • @jsdude005
  • Organize Chicago JavaScript Meetup
  • React, Redux and JavaScript Trainer
  • App to make learning fun again

Jump from 14,000ft

Marathon 2016, 2017

10,000 volts

international Javascript conference, London

We will cover

  1. What is State
  2. 4 types of React state
  3. 5 Use cases to Manage state
  4. Redux Core Concepts
  5. Context Api
  6. And we will have fun...

What is a state?

Think for a second...


  • It's summer time
  • You are sitting in the beach


Your state is: pretty RELAXED

Think for another second...


  • You are in a big Conference
  • Everyone is staring at you


Your state is: pretty nervous

This means state of your mind changes based on the situation

So what is a state?

State is something

  • That might change
  • Like: your mood, your confidence level
  • Or types of cheese you add in your sandwich

What is changing in this pic?

What does changes in Facebook/Youtube?

Due to user interaction.

Think about an App

ema-john

In a React App

You can think of 4 types of state

  1. Component State
    • State stays within the component
    • Can only be updated within that component

  2. Smart Component: HOC
    • Container vs Presentation Component
    • State still stays within the component
    • Pass state, event handlers via Props

React States

State in a React App

  1. Application State: Global State
    • Like: Session storage/Redux, database, etc.
    • Any component, anywhere in the app can access

  2. Provided State: Since React 16.3
    • Each context has a provider and a consumer
    • No need to pass context as prop-drilling
    • Available anywhere under the component tree

React States



React State management pattern

Use Case - 1

Building from scratch


Think in React

Start with a mockup

Data you have


							[
							  {name: "Lenovo", price: "$649.99", stock: 12, ...},
							  {name:"Mac the money sucker",price:"$1999.99",stock:8, ...},
							  {name: "Dongle", price: "$29.99", stock: 12, ...},
							  {name: "iPod Touch", price: "$699.99", stock: 1, ...},
							  {name: "iPhone X", price: "$999.99", stock: 31, ...},
							  {name: "Nexus 7", price: "$199.99", stock: 0, ...},
							];
												

Think in React

Render State

Handle a product toggle

Can we make state simpler?

  • Try to Avoid changing data you get from the API
  • Handle Derived Property in Render
  • Avoid 2 or more state change with one event

componentDidMount() {
  Promise.all([ 
    api.shop.getProducts(), 
    api.shop.getCurrentOrder()
  ]).then(([products, order]) => {
    // No pre-processing of our data from the server
    this.setState({ products, order });
  });
}
					

						getSelected(product) {
						  return this.state.order.find(p => p.id === product.id);
						}
											

If possible calculate derived properties of your data during render()

Toggle Product



toggleProductInOrder(product) {
  const order = this.state.order;
  const selectedProduct = this.getSelected(product);
	
  //Either add or remove the item in the order list
  const updatedOrder = selectedProduct
	? without(order, product) : concat(order, product) ;
	
  return api.shop.updateOrder(updatedOrder).then(newOrder =>{
    this.setState({ order: newOrder }); //update state
  });
}

Manage State in React

Digestible example

Compute From states


	class MyComponent extends Component {
	  constructor(props) {
	    super(props);
	    this.state = { message: props.message + "!" };
	  }
	  getDerivedStateFromProps(props) {
	    this.setState({ message: props.message + "!" });
	  }
	  render() {
	    return (
	      
{this.state.message}
); } }

Are you using states where you don't have to?

Just read from the props/state


	render() {
	  const excitedMessage = this.props.message + "!";
	  return (
{excitedMessage}
); }

Avoid using state for data which can be calculated from props or other state

Use Case - 2

Where to put the state?

Identify Component Hierarchy

  • Draw boxes around component
  • Use Single responsibility principle
  • One component should ideally do one thing
  • Think about re-usability

Name your components

Identify UI State

Where to put the state

  1. Identify component that just has to render
  2. Put state in the common owner in the higher up
  3. If you don't find a common owner, create one

(Apply these 3 rules)

  • ProductContainer doesn't have filters information
  • SearchBar doesn't have product list
  • cart doesn't have selected product price
  • Created Shop Component to contain the state

working code


Summary

  • Try not to change data you get from server
  • Avoid storing data in this.state which can be calculated from props/state
  • Try to put derived property in render()
  • Try to avoid single event changing multiple state


Handle state in React

Quiz Time ???

What is the name of the app?

Use Case - 3

You have a little mess

Your manager tells you to

Add more features...

More features mean...

  • More components
  • More data, more props has to pass data
  • More event handler has to be managed
  • State grows and becomes complicated

  • And you create more mess...


But Don't worry: the bigger is the mess, this higher is the job security

Redux

Will start knocking at your door

Redux will ask you

  • Put app state out of your component
  • Create state as plain objects and arrays
  • Describe changes as plain objects
  • Handling changes as pure functions


None of these is a must to build an app

Adding Redux

  • Will add an indirection to your problem
  • Will shift the complexity in a different direction
  • Could make your situation WORSE

Is redux a must?

Asses your application

  • How many sibling Components have to communicate?
  • Does child component contain state from parent component?
  • How many different views need to share state?

Assess your team

  • Do a proof of concept in a feature branch
  • Explore how it solves the problem before diving into it
  • Does team understand: Redux core concepts.
  • Can handle extra level of complexity
  • Immutabilty, pure function, etc.

Lighter State Management

  • Higher Order Component
  • Local Storage
  • Route Parameter
  • Database (if you are already using it)



ema-john

Summary

  1. Think in React
  2. Read about composition
  3. Find where to put your state
  4. You Might Not Need Redux
  5. You can apply ideas from Redux without using it
  6. Come back to Redux if you find a real need for it


React state without Redux

Quiz Time ???

Who was the guy knocking at the door?

Use Case - 4

State management library: Redux


When you need to share state a lot

What if we put them in one place

Store

  • Holds application state
  • Only one store for all its application state
  • Single source of truth

How will we change the state?

Action

  • Actions
  • Action container

{
  type: 'ADD_TODO',
  text: 'Take 8 bathroom breaks'
}
						
  • dispatch action
  • But you didn't tell how state will change?

    Actually state will not change

    we will create a new state with the change

    
    function add(x, y){
      return x + y;
    }
    						
    
    add(1, 2); // output is 3
    add(1, 2); // output still is 3
    add(1, 2); // WILL ALWAYS output 3
    						

    reducer

    • Actions describe the fact that something happened
    • Action don't specify how the application's state should change
    • How state will change will be defined by reducer
    
    case ADD_TODO:
      return [
      ...todos,
      {
        text: action.text,
        completed: false
      }
    ]
    						

    reducer

    Data Flow

    • Action is a plain object describing what happened
    • Call store.dispatch(action) from anywhere in your app
    • Store calls the reducer function you gave for the given action
    • In root reducer you may combine multiple reducers into a single state tree
    • Store saves the complete state tree returned by the root reducer


    Redux state management

    Basic Building Block

    • Store
    • Action
    • Dispatch
    • Reducer

    ref: unit test ract redux app

    See some code

    github.com/khan4019/redux-todo



    state management

    Is Redux the only option?

    MobX is one option

    Redux MobX
    single store multiple stores
    flat state nested state
    functional programming OOP & reactive programming
    immutable mutable
    plain JavaScript “magic” JavaScript
    more boilerplate less boilerplate

    MobX , Redux or MobX , MobX vs Redux

    Other options

    Quiz Time ???



    How many guys were sleeping in the class room?

    Use Case -5

    Sharing Context

    New cool kid in the corner since React 16.3

    App Level settings?

    • Pass data through the component tree?
    • Pass data manually every level as props
    • Like: Current locale, theme, user Context

    Context

    • Gives you the power to pass data to child component
    • Without passing props down manually at every level
    • Share values like these between components

    Create Context

    API

    Don’t use context just to avoid passing props a few levels down.

    Advanced Usage

    • Dynamic Context
    • Updating Context from a Nested Component
    • Consuming Multiple Contexts
    • Accessing Context in Life cycle Methods
    • Consuming Context with a HOC
    • Forwarding Refs to Context Consumers

    Context API

    Use Context as State Manager



    React Waterfall



    Replacing Redux with the new React context API

    Learn New thing

    Learn react by building

    thatjsdude.com

    Email: khan4019@gmail.com

    Free tip

    Tight on food budget

    Want to save more...

    Save even more...

    Ultimate saver...

    Thank you

    -Slides: @jsDude005

    -Website: thatjsude.com


    -Email: khan4019@gmail.com