Now I get it, your problem is not really recursion itself but immutability. You can do it with a ref.
type opts = {foo: React.element}
@val
external registerSW: opts => unit => unit = "registerSW"
let updateSWRef = ref(ignore)
updateSWRef :=
registerSW({foo: <button onClick={_ => updateSWRef.contents()} />})