Props And State

Props

Components are

independent,

reusable

pieces of UI

Components can be

functions.

Components can be

classes.

Either Way:
Components act like functions

props are the input,

jsx is the output.

When a function is called with new input, the output is returned again.

When a component is called with new props, the output is rendered again.

State

State

is

similar

to

Props

State is

private,

and

fully controlled

by the Component.

State allows a component to be truly Portable.

Prop changes act like function calls.

State changes act like function recursion.

Lifecycle

Mounting

  1. constructor
  2. componentWillMount
  3. render
  4. componentDidMount

Constructor

This is a place where it is ok to fork props and state. 

class Counter {
    constructor(props) {
      super(props);
      this.state = {
        count: props.count;
      };
    }
}

This is not an invitation to begin a synchronization dance between state and props.

Component Will Mount

Setting state here will not trigger a render

class Counter extends Component {
    componentWillMount() {
      this.setState({
        count: props.count
      });
    }
}

This is primarily for server side rendering. I don't think there is any reason for us to use this method.

Render

  1. Should not make http requests
  2. Should not modify component state
  3. Should not directly interact with the dom
  4. Should not perform side effects

Component Did Mount

  1. Good place for performing side effects
  2. Good place to manipulate DOM
  3. Good place to make http requests or similar actions
  4. Setting state will trigger a render
class Counter extends React.Component {
  componentDidMount() {
    this.textInput.focusTextInput();
    this.props.fetchInitialCount();
  }

  render() {
    return (
      <SimpleTextInput
        ref={(input) => { this.textInput = input; }} />
    );
  }
}


Updating

  1. componentWillReceiveProps
  2. shouldComponentUpdate
  3. componentWillUpdate
  4. render
  5. componentDidUpdate

Component Will Receive Props

  1. Invoked before a component receives props
  2. An ok place to set state based on props
  3. May (will) be called when props have not changed
  4. Only called in updates NOT mounts

Should Component Update

  1. Do not set state here
  2. Do not make http requests
  3. Do not manipulate dom
  4. Only called in updates NOT mounts

Component Will Update

  1. Do not set state here
  2. Do not make http requests
  3. Do not dispatch redux actions
  4. Do not manipulate the dom
  5. Do prepare data before renders here

Component Did Update

  1. Do not set state here
  2. Make http requests if you compare props and state changes
  3. Dispatch redux actions if you compare props and state changes
  4. Manipulate the dom if you compare props and state changes

Unmounting

  1. componentWillUnmount

Component Will Unmount

  1. Do not set state here
  2. Cancel network requests
  3. Remove Event listeners
  4. Clean up DOM

Lifting State Up

In React if two components need the same data, that state must be hoisted to a common parent and shared via props.

Incrementer

Timer

Parent

Text

Scrolling

Incrementer

Color Changing

Timer

Parent

Color Changing

Scrolling

Incrementer

Scrolling

Color Changing

Timer

Parent

Incrementer

Timer

Color Changing

Scrolling

Parent

 

Incrementer

Timer

Current Color Tracking

Scroll Position Tracking

Scroll Event Handler

Color Change Handler

Parent

 

Current Color Formatting

Scroll Position Velocity Calculating

Incrementer

 

Current Color Tinting

Scroll Position Polling

Timer

Current Color Tracking

Scroll Position Tracking

Scroll Event Handler

Color Change Handler

Parent

What if the nearest common parent was not a simple container, but another complex component in charge of its own state and props?

Please Be Mindful

When Lifting State

Application State

In Redux if two components need the same data, that state must be calculated with a reducer and mapped to component props.

Incrementer

Timer

Parent

Reducer

Scroll Position

Current Color

Connect

Any State

Any Handlers

Connect

Any State,

Any Handlers

Prefer connecting components with Redux to over lifting state when you need portability within the context of a single application

Prefer lifting state over connecting components with Redux when you need portability of component groups between applications (open source).

Takeaways

Reconciling or Synchronizing Props and State is Unacceptable

Forking Props and State is Acceptable, But Dangerous

Use props as an expression of UI

Not As a Message Utility

Use state as an expression of UI

Not As a Message Utility

If you must lift state, make a Container Component

But please, for the love of Gozer, consider just using Redux.

Props And State

By Ryan Moore

Props And State

  • 382