DEV Community

Cover image for ReactHooks: useState
Christian Hansen
Christian Hansen

Posted on

ReactHooks: useState

State in Functional Components

A functional React component is a function which takes props in as an argument, its name begins with a capital, and returns JSX. Functional components can be written with arrow functions and standard functions. Below are some examples of Functional Components.

function Hello(props) {
  return <h1>Hello, {props.name}</h1>
}

const Hi = ({name}) => <h2>Hi, {name}</h2>

const Buttons = () => {
  return (
    <div>
      <button>Rain</button>
      <button>Snow</button>
    </div>
  )
}

function App() {
  return (
    <div>
      <Hello name={"World"}/>
      <Hi name={"Jim"} />
      <Buttons />
    </div>
  );
}

Prior to the release of hooks, local state could only be added to a class component. Functional components were called presentational components because they could only present data passed to them.

function CounterWithOutState() {
  return <button>0</button>;
}

class Counter extends React.Component {
  state = { count: 0 };

  onClick = () => {
    this.setState({
      count: this.state.count + 1
    });
  };

  render() {
    return <button onClick={this.onClick}>{this.state.count}</button>;
  }
}

Class components are still supported and there are no plans to remove them from the API. The addition of hooks provides a different way to add state that some may find more desirable. Note that hooks can not be used within classes.

useState API

Below is an example of the useState hook.

function Counter() {
  const [count, setCount] = React.useState(0);
  const onClick = () => setCount(count + 1);
  return <button onClick={onClick}>{count}</button>;
}

Initial state is passed into useState and an array of two things is returned. The first item in the array is a reference to the state and the second is a function to update the state. Whatever that is passed into the function, which in this example is called setCount, will overwrite the currently stored state. The two items in the array can be named to whatever fits the situation best, which helps the two be described better.

The updater function can also be passed a function instead of the new value. This function will have the previous value passed in as the first argument. This function will be run and the return value will be the new value of the state.

 const onClick = () => setCount(prevCount => prevCount + 1);

The useState hook can be used multiple times in the function. Below are two different examples. One that uses useState once and the other uses useState twice. Which one is better is probably personal preference, however both could be taken to extremes in which code would be difficult to understand.

  // One useState

  const [state, setState] = React.useState({
    input: '',
    list: [],
  });
  const onChange = event => setState({
    ...state,
    input: event.target.value,
  })
  const onClick = () => setState({
    ...state,
    list: [...state.list, state.input]
  })

 // Two useStates

 const [input, setInput] = React.useState("initial");
 const [list, setList] = React.useState([]);

 const onChange = event => setInput(event.target.value)
 const onClick = () => setList([...list, input])

Latest comments (0)