From 9c133cb5f0d8aaf6bce4a54ec19476349940a6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Gr=C3=B6hling?= Date: Fri, 3 Jan 2025 12:38:50 +0100 Subject: [PATCH] feat: document ref for self-referencing --- pages/docs/manual/v11.0.0/mutation.mdx | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pages/docs/manual/v11.0.0/mutation.mdx b/pages/docs/manual/v11.0.0/mutation.mdx index 33d4050f0..e8da62729 100644 --- a/pages/docs/manual/v11.0.0/mutation.mdx +++ b/pages/docs/manual/v11.0.0/mutation.mdx @@ -73,3 +73,47 @@ Note that the previous binding `five` stays `5`, since it got the underlying ite ## Tip & Tricks Before reaching for `ref`, know that you can achieve lightweight, local "mutations" through [overriding let bindings](let-binding.md#binding-shadowing). + +### Self-Referencing Assignments + +There are scenarios where using a mutable `ref` binding becomes necessary, particularly when dealing with self-referencing. This is common when working with functions that return a value and accept a callback that uses that return value. In such cases, you need to initialize a mutable `ref` binding and then assign to it. Here's an example: + + + +```res example +// hypothetic "showDialog" function shows the given `~content: JSX.element` +// in the dialog. It returns a cleanup function that closes/removes the dialog. +@val external showDialog: (~content: Jsx.element) => unit => unit = "showDialog" + +// We want render a "Close" button in the `~content` that will call the +// returned cleanup function when clicked. This requires a mutable binding. +// First initialize it with a dummy function that has the same signature as +// our cleanup function. +let cleanupDialog = ref(() => ()) + +// assign to the ref and self-refer to the value in the event handler +cleanupDialog := + showDialog( + ~content=
+ +
, + ) +``` +```js +var cleanupDialog = { + contents: (function () {}) +}; + +cleanupDialog.contents = showDialog(JsxRuntime.jsx("div", { + children: JsxRuntime.jsx("button", { + children: "Close", + onClick: (function (param) { + cleanupDialog.contents(); + }) + }) + })); +``` + +
\ No newline at end of file