reason-react-brunch
Version:
React bindings for Reason, modified to work with brunch and bucklescript
47 lines (34 loc) • 1.98 kB
Markdown
---
title: React Ref
---
_Not to be confused with Reason `ref`, the language feature that enables mutation_.
A ReasonReact `ref` would be just another instance variable. You'd type it as `ReasonReact.reactRef` if it's attached to a custom component, and `Dom.element` if it's attached to a React DOM element.
```reason
type state = {
isOpen: bool,
mySectionRef: ref(option(ReasonReact.reactRef))
};
let setSectionRef = (theRef, {ReasonReact.state}) => {
state.mySectionRef := Js.Nullable.toOption(theRef);
/* wondering about Js.Nullable.toOption? See the note below */
};
let component = ReasonReact.reducerComponent("MyPanel");
let make = (~className="", _children) => {
...component,
initialState: () => {isOpen: false, mySectionRef: ref(None)},
reducer: ...,
render: (self) => <Section1 ref={self.handle(setSectionRef)} />
};
```
Attaching to a React DOM element looks the same: `state.mySectionRef = {myDivRef: Js.Nullable.toOption(theRef)}`.
**Note** how [ReactJS refs can be null](https://github.com/facebook/react/issues/9328#issuecomment-298438237). Which is why `theRef` and `myDivRef` are converted from a [JS nullable](https://bucklescript.github.io/docs/en/null-undefined-option.html) to an OCaml `option` (Some/None). When you use the ref, you'll be forced to handle the null case through a `switch`, which prevents subtle errors!
**You must follow the instanceVars convention in the previous section for ref**.
ReasonReact ref only accept callbacks. The string `ref` from ReactJS is deprecated.
We also expose an escape hatch `ReasonReact.refToJsObj` of type `ReasonReact.reactRef => Js.t {..}`, which turns your ref into a JS object you can freely use; **this is only used to access ReactJS component class methods**.
```reason
let handleClick = (event, self) =>
switch (self.state.mySectionRef^) {
| None => ()
| Some(r) => ReasonReact.refToJsObj(r)##someMethod(1, 2, 3) /* I solemnly swear that I am up to no good */
};
```