Skip to content

Latest commit

 

History

History
134 lines (102 loc) · 3.42 KB

hooks-state.mdx

File metadata and controls

134 lines (102 loc) · 3.42 KB
title description canonical
useState Hook
Details about the useState React hook in ReScript
/docs/react/latest/hooks-state

useState

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

Usage

<CodeTab labels={["ReScript", "JS Output"]}>

let (state, setState) = React.useState(_ => initialState)
var match = React.useState(function () {
      return initialState;
    });

var state = match[0];

var setState = match[1];

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.

Examples

Using State for a Text Input

@react.component
let make = () => {
  let (text, setText) = React.useState(_ => "");

  let onChange = evt => {
    ReactEvent.Form.preventDefault(evt)
    let value = ReactEvent.Form.target(evt)["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.

<CodeTab labels={["ReScript", "JS Output"]}>

// ThemeContainer.res
module ControlPanel = {
  @react.component
  let make = (~setDarkmode, ~darkmode) => {
    let onClick = evt => {
      ReactEvent.Mouse.preventDefault(evt)
      setDarkmode(prev => !prev)
    }

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

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

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

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

  <div className>
    <section>
      <h1> {React.string("More Infos about ReScript")} </h1> content
    </section>
    <ControlPanel darkmode setDarkmode />
  </div>
}
function ControlPanel(Props) {
  var setDarkmode = Props.setDarkmode;
  var darkmode = Props.darkmode;
  var onClick = function (evt) {
    evt.preventDefault();
    return Curry._1(setDarkmode, (function (prev) {
                  return !prev;
                }));
  };
  var toggleText = "Switch to " + ((
      darkmode ? "light" : "dark"
    ) + " theme");
  return React.createElement("div", undefined, React.createElement("button", {
                  onClick: onClick
                }, toggleText));
}

function ThemeContainer(Props) {
  var content = Props.content;
  var match = React.useState(function () {
        return false;
      });
  var darkmode = match[0];
  var className = darkmode ? "theme-dark" : "theme-light";
  return React.createElement("div", {
              className: className
            }, React.createElement("section", undefined, React.createElement("h1", undefined, "More Infos about ReScript"), content), React.createElement(Playground$ControlPanel, {
                  setDarkmode: match[1],
                  darkmode: darkmode
                }));
}

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.