Skip to content

Commit

Permalink
Update more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
chenglou committed Aug 7, 2018
1 parent 20b6bb4 commit 433acd5
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 35 deletions.
15 changes: 0 additions & 15 deletions docs/children.md
Expand Up @@ -129,18 +129,3 @@ Here are some use-cases for children spread + Reason built-in data structures:
```reason
<Layout> ...(ThreeRows(<div />, child2, child3)) </Layout>
```

### Pitfall

Following the above section's reasoning, this code should work:

```reason
let children = [| <div /> |];
<div> ...children </div>; /* <--- this line */
```

It _does_ work for custom components (upper-case), But it doesn't for DOM components (lower-cased). This is due to some bindings-related constraints; we'll make this better in the future! In the meantime, for passing to DOM element, e.g. `<div className=bar> ...children </div>` use the following:

```reason
ReasonReact.createDomElement("div", ~props={"className": bar}, children);
```
16 changes: 4 additions & 12 deletions docs/clone-element.md
Expand Up @@ -4,25 +4,17 @@ title: cloneElement

Signature: `let cloneElement: (reactElement, ~props: Js.t({..})=?, 'anyChildrenType) => reactElement`

Same as ReactJS' [cloneElement](https://reactjs.org/docs/react-api.html#cloneelement). However, adding extra props to a ReasonReact component doesn't make sense; you'd use a [**render prop**](https://reactjs.org/docs/render-props.html). Therefore, `ReasonReact.cloneElement` is only used for edge-case interop situations. For example, `data-*` attributes aren't syntactically valid as a function label. The following doesn't parse:
Same as ReactJS' [cloneElement](https://reactjs.org/docs/react-api.html#cloneelement). However, adding extra props to a ReasonReact component doesn't make sense; you'd use a [**render prop**](https://reactjs.org/docs/render-props.html). Therefore, `ReasonReact.cloneElement` is only used in edge-cases to convert over existing code.

```reason
<div data-payload=1 className="foo" />
```

You'd use `cloneElement` to circumvent it like so:

```reason
let myElement =
let clonedElement =
ReasonReact.cloneElement(
<div className="foo" />,
~props={"data-payload": 1},
~props={"payload": 1},
[||]
);
```

This will assign the extra `data-payload` props (**untyped**, be careful!) onto the `div`, through a clever, syntactically valid use of Reason's JS object sugar for [BuckleScript objects](https://bucklescript.github.io/docs/en/object.html#object-as-record).

For non-DOM components, you need to use valid prop names.
The `props` value is unsafe, be careful!

You can also use `cloneElement` to simulate [prop spreading](props-spread.md), but this is discouraged in ReasonReact.
8 changes: 5 additions & 3 deletions docs/dom.md
Expand Up @@ -4,14 +4,16 @@ title: Working with DOM

## ReactDOM

ReasonReact's ReactDOM module is called `ReactDOMRe`. The module exposes helpers that work with familiar ReactJS idioms. For example, to access `event.target.value`, you can do `ReactDOMRe.domElementToObj(ReactEventRe.Form.target(event))##value`.
ReasonReact's ReactDOM module is called `ReactDOMRe`. The module exposes helpers that work with familiar ReactJS idioms. For example, to access `event.target.value`, you can do `ReactEvent.Form.target(event)##value`.

- `render` : `(ReasonReact.reactElement, Dom.element) => unit`
- `unmountComponentAtNode` : `Dom.element => unit`
- `findDOMNode` : `ReasonReact.reactRef => Dom.element`
- `hydrate` : `(ReasonReact.reactElement, Dom.element) => unit`
- `objToDOMProps` : `Js.t({..}) => reactDOMProps` (see use-case in [Invalid Prop Name](invalid-prop-name.md))
- `domElementToObj` : `Dom.element => Js.t({..})`: turns a DOM element into a Js object whose fields that you can dangerously access.
- `objToDOMProps` : `Js.t({..}) => ReactDOMRe.props` (see use-case in [Invalid Prop Name](invalid-prop-name.md))
- `createElement` : `(string, ~props: ReactDOMRe.props=?, array(ReasonReact.reactElement)) => ReasonReact.reactElement`: the call that lower-case JSX turns into.
- `createElementVariadic`: same as above, but a less performant version, used when there's a children spread and not a static array at the call site: `<div>...myChildren</div>`.
- `domElementToObj` : `Dom.element => Js.t({..})`: turns a DOM element into a Js object whose fields that you can dangerously access. Usually not needed

And 4 convenience utilities:

Expand Down
10 changes: 8 additions & 2 deletions docs/event.md
Expand Up @@ -2,12 +2,18 @@
title: Event
---

ReasonReact events map cleanly to ReactJS [synthetic events](https://reactjs.org/docs/events.html). More info in the [inline docs](https://github.com/reasonml/reason-react/blob/master/src/ReactEventRe.rei#L1).
ReasonReact events map cleanly to ReactJS [synthetic events](https://reactjs.org/docs/events.html). More info in the [inline docs](https://github.com/reasonml/reason-react/blob/master/src/ReactEvent.rei#L1).

If you're accessing fields on your event object, like `event.target.value`, you'd use a combination of a `ReactDOMRe` helper and [BuckleScript's `##` object access FFI](https://bucklescript.github.io/docs/en/object.html#accessors):

```reason
ReactDOMRe.domElementToObj(ReactEventRe.Form.target(event))##value;
ReactEvent.Form.target(event)##value;
```

Or, equivalently, using fast pipe:

```reason
event->ReactEvent.Form.target##value;
```

More info on the `ReactDOMRe` module below in the [Working with DOM](dom.md) section.
10 changes: 9 additions & 1 deletion docs/invalid-prop-name.md
Expand Up @@ -6,6 +6,14 @@ Prop names like `type` (as in `<input type="text" />`) aren't syntactically vali

For `aria-*`: use the camelCased `ariaFoo`. E.g. `ariaLabel`. For DOM components, we'll translate it to `aria-label` under the hood.

For `data-*`, this is a bit trickier; words with `-` in them aren't valid in Reason/OCaml. When you do want to write them, e.g. `<div data-name="click me" />`, use [`cloneElement`](clone-element.md) as a workaround.
For `data-*`, this is a bit trickier; words with `-` in them aren't valid in Reason/OCaml. When you do want to write them, e.g. `<div data-name="click me" />`, use the following:

```reason
ReactDOMRe.createElementVariadic(
"div",
~props=(ReactDOMRe.objToDOMProps({"data-name": "click me"})),
[||]
)
```

For non-DOM components, you need to pick valid prop names.
2 changes: 1 addition & 1 deletion docs/state-actions-reducer.md
Expand Up @@ -134,7 +134,7 @@ Notice the return value of `reducer`? The `ReasonReact.Update` part. Instead of
- The `action` type's variants can carry a payload: `onClick=(data => self.send(Click(data.foo)))`.
- Don't pass the whole event into the action variant's payload. ReactJS events are pooled; by the time you intercept the action in the `reducer`, the event's already recycled.
- `reducer` **must** be pure! Aka don't do side-effects in them directly. You'll thank us when we enable the upcoming concurrent React (Fiber). Use `SideEffects` or `UpdateWithSideEffects` to enqueue a side-effect. The side-effect (the callback) will be executed after the state setting, but before the next render.
- If you need to do e.g. `ReactEventRe.BlablaEvent.preventDefault(event)`, do it in `self.send`, before returning the action type. Again, `reducer` must be pure.
- If you need to do e.g. `ReactEvent.BlablaEvent.preventDefault(event)`, do it in `self.send`, before returning the action type. Again, `reducer` must be pure.
- Feel free to trigger another action in `SideEffects` and `UpdateWithSideEffects`, e.g. `UpdateWithSideEffects(newState, (self) => self.send(Click))`.
- If your state only holds instance variables, it also means (by the convention in the instance variables section) that your component only contains `self.handle`, no `self.send`. You still need to specify a `reducer` like so: `reducer: ((), _state) => ReasonReact.NoUpdate`. Otherwise you'll get a `variable cannot be generalized` type error.

Expand Down
2 changes: 1 addition & 1 deletion src/README.md
Expand Up @@ -4,6 +4,6 @@ Files overview:

- `ReactDOMRe`: bindings to ReactDOM.
- `ReactDOMServerRe`: bindings to ReactDOMServer.
- `ReactEventRe`: bindings to React's custom events system.
- `ReactEvent`: bindings to React's custom events system.
- `ReasonReact`: core React bindings.
- `ReasonReactOptimizedCreateClass`: our reasonReact component initialization uses React's createClass under the hood. This file's a tweaked version of it, with all the dependencies, warnings and invariants commented out (we don't need any of them anymore! Our types obsoleted them =D).

0 comments on commit 433acd5

Please sign in to comment.