React State

State is similar to Props. It's variables we can use in our components, with one key difference: Props can't change. State can.

Note: This section uses destructuring, feel free to go back and reread if you've forgotten how it works.

React.useState(

React.useState( is what React calls a 'hook'. Hooks go inside your component functions, usually near the top of the function.

const Counter = (props) => {
  const [count, setCount] = React.useState(0)
  return <p>Hello</p>
}

Let's break down this line of code:

const [count, setCount] = React.useState(0)
//     ^^^^^  ^^^^^^^^                   ^

0 is the initial value of the piece of state we're setting up. In this case the number 0.

count is a const which has the current value of that piece of state. You can talk about count in your program.

setCount is a function which sets the state (count). If we want to update the state we call this function and pass the new value. e.g. setCount(5) would set count to 5.

React rerendering

Up until now the model of React is that your component functions get called once, return some JSX and React renders that JSX into the DOM and onto your screen!

With state this model needs adjusting:

React keeps track of props and state, if props or state change, it reruns your component function, calculates the JSX and keeps the DOM updated with the most up-to-date JSX for you.

State Example

In the example above you can see that the count state is initially set to 0 and rendered onto the screen.

When the button is pressed the setCount( function is called, this changes state causing react to rerender the component.

Upon rerender count is now 1.

More examples

Multiple state variables:

const Counter = (props) => {
  const [count1, setCount1] = React.useState(0)
  const [count2, setCount2] = React.useState(0)
  return <div>
    <p>{count1}</p>
    <p>{count2}</p>
    <button onClick={() => setCount1(count1 + 1)}>Add to 1</button>
    <button onClick={() => setCount2(count2 + 1)}>Add to 2</button>
  </div>
}

String state:

const Counter = (props) => {
  const [string, setString] = React.useState("Hello")
  return <div>
    <p>{string}</p>
    <input onChange={(e) => setString(e.target.value)} />
  </div>
}

Array of objects:

const Counter = (props) => {
  const [coders, setCoders] = React.useState([
    { name: 'Ada', born: 1816 },
    { name: 'Alice', born: 1990 },
    { name: 'Susan', born: 1960 },
  ])
  return <div>
    {coders.map(coder => <p>{coder.name}</p>)}
  </div>
}

State allows you to indirectly modify props

Let's go back to our Star component from earlier on: <Stars stars={5} color="yellow" />

const Counter = (props) => {
  const [stars, setStars] = React.useState(0)
  return <div>
    <Stars stars={stars} color="yellow" />
    <button onClick={() => setStars(stars + 1)}>Add star</button>
  </div>
}

Using state, each time the button is pressed the value of the stars= prop increases by one. Whenever props change like this (via State) React rerenders calling any effected component functions again.