Skip to content

Add React interopt guide #886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion data/sidebar_react_latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"Guides": [
"beyond-jsx",
"forwarding-refs",
"extensions-of-props"
"extensions-of-props",
"interopt"
]
}
122 changes: 122 additions & 0 deletions pages/docs/react/latest/interopt.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
title: Interopt
description: "Reusing existing React components"
canonical: "/docs/react/latest/interopt"
---

# Interopt

Reusing existing React components in ReScript is straightforward.
This guide will walk you through the steps required to import and use React components within ReScript,
including defining component props and handling various import scenarios.

## Basic Example

To reuse a React component in ReScript, create a new module, specify the component's location, and define its props.

```js
import Confetti from "react-confetti"

const App = () => {
<Confetti width={300} height={300} />
}
```

```res
module Confetti = {
@module("react-confetti")
@react.component
external make : (~width:int, ~height: int) => React.element = "default"
}

// Assuming we are in App.res
@react.component
let make = () => {
<Confetti width={300} height={300} />
}
```

## Importing from Relative Paths

You can import components from relative file paths using the `@module` attribute.
Use "default" to indicate the default export, or specify a named export if needed.

### Named Export Example

```res
// Equivalent of import { Foo } from "bar"
module Foo = {
@module("bar")
@react.component
external make : () => React.element = "Foo"
}
```

## Defining Props Types

You can define a separate type for your component's props within the module.

### Props Type Example

```res
module Confetti = {
type confettiProps = {
width: int,
height: int,
}

@module("react-confetti") @react.component(: confettiProps)
external make: confettiProps => React.element = "default"
}

@react.component
let make = () => {
<Confetti width={300} height={300} />
}
```

## Optional Props

To define optional props, use the `?` symbol.

```res
module Confetti = {
type confettiProps = {
width: int,
height: int,
initialVelocityX?: int,
initialVelocityY?: int,
}

@module("react-confetti") @react.component(: confettiProps)
external make: confettiProps => React.element = "default"
}

@react.component
let make = () => {
<Confetti width={300} height={300} />
}
```

## Extending Built-in DOM Nodes

To accept existing DOM props for a component, extend the `JsxDOM.domProps` type.

```res
module Foo = {
type fooProps = {
...JsxDOM.domProps,
customProp: string,
}

@module("foo") @react.component(: fooProps)
external make: fooProps => React.element = "default"
}

@react.component
let make = () => {
<Foo width={"300px"} height={"300px"} customProp="bar" />
}
```

In this example `width` and `height` can be set because `JsxDOM.domProps` was spread into `fooProps`.