Skip to content

The React State

New Course Coming Soon:

Get Really Good at Git

How to interact with the state of your components

Setting the default state

In the Component constructor, initialize this.state. For example the BlogPostExcerpt component might have a clicked state:

class BlogPostExcerpt extends Component {
  constructor(props) {
    super(props)
    this.state = { clicked: false }
  }

  render() {
    return (
      <div>
        <h1>Title</h1>
        <p>Description</p>
      </div>
    )
  }
}

Accessing the state

The clicked state can be accessed by referencing this.state.clicked:

class BlogPostExcerpt extends Component {
  constructor(props) {
    super(props)
    this.state = { clicked: false }
  }

  render() {
    return (
      <div>
        <h1>Title</h1>
        <p>Description</p>
        <p>Clicked: {this.state.clicked}</p>
      </div>
    )
  }
}

Mutating the state

A state should never be mutated by using

this.state.clicked = true

Instead, you should always use setState() instead, passing it an object:

this.setState({ clicked: true })

The object can contain a subset, or a superset, of the state. Only the properties you pass will be mutated, the ones omitted will be left in their current state.

Why you should always use setState()

The reason is that using this method, React knows that the state has changed. It will then start the series of events that will lead to the Component being re-rendered, along with any DOM update.

Unidirectional Data Flow

A state is always owned by one Component. Any data that’s affected by this state can only affect Components below it: its children.

Changing the state on a Component will never affect its parent, or its siblings, or any other Component in the application: just its children.

This is the reason the state is often moved up in the Component tree.

Moving the State Up in the Tree

Because of the Unidirectional Data Flow rule, if two components need to share state, the state needs to be moved up to a common ancestor.

Many times the closest ancestor is the best place to manage the state, but it’s not a mandatory rule.

The state is passed down to the components that need that value via props:

class Converter extends React.Component {
  constructor(props) {
    super(props)
    this.state = { currency: '€' }
  }

  render() {
    return (
      <div>
        <Display currency={this.state.currency} />
        <CurrencySwitcher currency={this.state.currency} />
      </div>
    )
  }
}

The state can be mutated by a child component by passing a mutating function down as a prop:

class Converter extends React.Component {
  constructor(props) {
    super(props)
    this.state = { currency: '€' }
  }

  handleChangeCurrency = event => {
    this.setState({ currency: this.state.currency === '€' ? '$' : '€' })
  }

  render() {
    return (
      <div>
        <Display currency={this.state.currency} />
        <CurrencySwitcher
          currency={this.state.currency}
          handleChangeCurrency={this.handleChangeCurrency}
        />
      </div>
    )
  }
}

const CurrencySwitcher = props => {
  return (
    <button onClick={props.handleChangeCurrency}>
      Current currency is {props.currency}. Change it!
    </button>
  )
}

const Display = props => {
  return <p>Current currency is {props.currency}.</p>
}
Are you intimidated by Git? Can’t figure out merge vs rebase? Are you afraid of screwing up something any time you have to do something in Git? Do you rely on ChatGPT or random people’s answer on StackOverflow to fix your problems? Your coworkers are tired of explaining Git to you all the time? Git is something we all need to use, but few of us really master it. I created this course to improve your Git (and GitHub) knowledge at a radical level. A course that helps you feel less frustrated with Git. Launching Summer 2024. Join the waiting list!
→ Get my React Beginner's Handbook
→ Read my full React Tutorial on The Valley of Code

Here is how can I help you: