diff --git a/data/sidebar_react_latest.json b/data/sidebar_react_latest.json index 21827eb9d..758517284 100644 --- a/data/sidebar_react_latest.json +++ b/data/sidebar_react_latest.json @@ -12,6 +12,7 @@ "events", "refs-and-the-dom", "context", + "memo", "styling", "router", "lazy-components", diff --git a/pages/docs/react/latest/memo.mdx b/pages/docs/react/latest/memo.mdx new file mode 100644 index 000000000..34b05a8c4 --- /dev/null +++ b/pages/docs/react/latest/memo.mdx @@ -0,0 +1,133 @@ +--- +title: memo +description: "Using React.memo" +canonical: "/docs/react/latest/memo" +--- + +# memo + +`React.memo` lets you skip re-rendering a component when its props are unchanged. + +Wrap a component in memo to get a memoized version of that component. +This memoized version of your component will usually not be re-rendered when its parent component is re-rendered as long as its props have not changed. + +But React may still re-render it: memoization is a performance optimization, not a guarantee. + + + +```res +@react.component +let make = React.memo((~a: int, ~b: string) => { +
+ {React.int(a)} +
+ {React.string(b)} +
+}) +``` + +```js +import * as React from "react"; +import * as JsxRuntime from "react/jsx-runtime"; + +var make = React.memo(function (props) { + return JsxRuntime.jsxs("div", { + children: [ + props.a, + JsxRuntime.jsx("br", {}), + props.b + ] + }); + }); +``` + +
+ +## arePropsEqual + +In React, memo can accept an optional argument called "arePropsEqual". This function takes two arguments: the previous props and the new props of the component. +It should return true if the old and new props are the same, meaning the component will produce the same output and behavior with the new props as it did with the old ones. + +In ReScript, you can use the `arePropsEqual` function with the `React.memoCustomCompareProps` binding. However, `React.memoCustomCompareProps` cannot be combined with `@react.component`. + +To work around this, you can redefine the make binding: + + + +```res +@react.component +let make = (~disabled, ~onClick) => { + +} + +let make = React.memoCustomCompareProps(make, (p1, p2) => + p1.disabled == p2.disabled +) +``` + +```js +import * as React from "react"; +import * as JsxRuntime from "react/jsx-runtime"; + +function Playground(props) { + var onClick = props.onClick; + return JsxRuntime.jsx("button", { + children: "My button", + disabled: props.disabled, + onClick: (function (ev) { + onClick((ev.preventDefault(), undefined)); + }) + }); +} + +var make = React.memo(Playground, (function (p1, p2) { + return p1.disabled === p2.disabled; + })); +``` + + + + +Another approach is to use a custom prop type and remove the `@react.component` annotation. + + + +```res +type props = { + disabled: bool, + onClick: JsxEvent.Mouse.t => unit, +} + +let make = React.memoCustomCompareProps( + ({disabled, onClick}) => { + + }, + (p1, p2) => p1.disabled == p2.disabled, +) +``` + +```js +import * as React from "react"; +import * as JsxRuntime from "react/jsx-runtime"; + +var make = React.memo((function (param) { + var onClick = param.onClick; + return JsxRuntime.jsx("button", { + children: "My button", + disabled: param.disabled, + onClick: (function (ev) { + onClick(ev); + }) + }); + }), (function (p1, p2) { + return p1.disabled === p2.disabled; + })); +``` + +