Setting Initial State

A React component can access dynamic information in two ways: props and state

Unlike props, a component's state is not passed in from the outside. A component decides its own state.

To make a component have state, give a component a state property. The state property should be declared inside of a constructor method.:

class Example extends React.Component {
  constructor(props) {                // constructor method
    super(props);
    this.state = { mood: 'decent' };  // state property
  }

  render() {
    return <div></div>;
  }
}

<Example />

this.state = {}

This object represents the initial state of any component instance.

constructor() and super() are both features of ES6, not unique to React. More on them here and here.

Accessing a Component's state

To read a component's state, use the expression this.state.name-of-property

class TodayImFeeling extends React.Component {
  constructor(props) {
    super(props);
    this.state = { mood: 'decent' };
  }

  render() {
    return (
      <h1>
        I'm feeling {this.state.mood}!
      </h1>
    );
  }
}

Updating state with this.setState

A component can do more than just read its own state, it can also change its own state.

this.setState()

Takes two arguments: an _object _that will update the component's state and a callback. (You basically never need the callback)

this.setState({ hungry: true })

this.setState() takes an object and merges that object with the component's current state.

{
    hungry: true,
    mood: 'great'
}

Call this.setState from Another Function

The most common way to call this.setState() is to call a function that wraps a this.setState() call.

toggleMood() is the wrapper function below:

import React from 'react';
import ReactDOM from 'react-dom';

class Mood extends React.Component {
  constructor(props) {
    super(props);
    this.state = { mood: 'good' };
    this.toggleMood = this.toggleMood.bind(this);
  }

  toggleMood() {
    const newMood = this.state.mood == 'good' ? 'bad' : 'good';
    this.setState({ mood: newMood });
  }

  render() {
    return (
      <div>
        <h1>I'm feeling {this.state.mood}!</h1>
        <button onClick={this.toggleMood}>
          Click Me
        </button>
      </div>
    );
  }
}

ReactDOM.render(<Mood />, document.getElementById('app'));

Here is how <Mood />'s state would be set:

  1. A user triggers an onClick by clicking a <button>.
  2. When this listened-for event occurs, it calls an event handler function this.toggleMood()
  3. Inside the body of the event handler, this.setState() is called
  4. The component's state is changed!

.bind()

Due to the way that event handlers are bound in JavaScript , this.toggleMood() loses its this when used in <button onClick={this.toggleMood}>. Therefore, whenever you define an event handler that uses this, you need to add this.methodName = this.methodName.bind(this) to your constructor function.

import React from 'react';
import ReactDOM from 'react-dom';

const green = '#39D1B4';
const yellow = '#FFD712';

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = { color: green };
    this.changeColor = this.changeColor.bind(this);
  }

  changeColor() {
    const newColor = this.state.color == green ? yellow : green;
    this.setState({ color: newColor });
  }

  render() {
    return (
      <div style={{background:this.state.color}}>
        <h1>
          <button onClick={this.changeColor}>Change color</button>
        </h1>
      </div>
    );
  }
}
ReactDOM.render(<Toggle />, document.getElementById('app'));

this.setState() Automatically Calls render()

When the <button> is clicked, it calls changeColor() which calls this.setState() which updates this.state.color.

Since {{background:this.state.color}} is in render(), and this.setState() automatically calls render() the background is magically rendering without having to re-render <Toggle />.

results matching ""

    No results matching ""