Docs / rescript-react / useState Hook


React.useState returns a stateful value, and a function to update it.


ReScriptJS Output
let (state, setState) = React.useState(_ => initialState)

During the initial render, the returned state state is the same as the value passed as the first argument (initialState).

The setState function can be passed down to other components as well, which is useful for e.g. setting the state of a parent component by its children.


Using State for a Text Input

@react.component let make = () => { let (text, setText) = React.useState(_ => ""); let onChange = evt => { ReactEvent.Form.preventDefault(evt) let value =["value"] setText(_prev => value); } <div> <input onChange value=text /> </div> };

Passing setState to a Child Component

In this example, we are creating a ThemeContainer component that manages a darkmode boolean state and passes the setDarkmode function to a ControlPanel component to trigger the state changes.

ReScriptJS Output
// ThemeContainer.res
module ControlPanel = {
  let make = (~setDarkmode, ~darkmode) => {
    let onClick = evt => {
      setDarkmode(prev => !prev)

    let toggleText = "Switch to " ++ ((darkmode ? "light" : "dark") ++ " theme")

    <div> <button onClick> {React.string(toggleText)} </button> </div>

let make = (~content) => {
  let (darkmode, setDarkmode) = React.useState(_ => false)

  let className = darkmode ? "theme-dark" : "theme-light"

  <div className>
      <h1> {React.string("More Infos about ReScript")} </h1> content
    <ControlPanel darkmode setDarkmode />

Note that whenever setDarkmode is returning a new value (e.g. switching from true -> false), it will cause a re-render for ThemeContainer's className and the toggle text of its nested ControlPanel.

Uncurried Version

For cleaner JS output, you can use React.Uncurried.useState instead:

ReScriptJS Output
let (state, setState) = React.Uncurried.useState(_ => 0)

setState(. prev => prev + 1)