### Install ReasonReact Dependencies with Opam
Source: https://reasonml.github.io/reason-react/docs/en/installation
Installs the necessary native dependencies for ReasonReact development using the opam package manager. This includes Melange, Dune, Reason, and ReasonReact with its PPX extension.
```bash
opam install melange dune reason reason-react reason-react-ppx -y
```
--------------------------------
### Clone and Initialize ReasonReact Melange Template
Source: https://reasonml.github.io/reason-react/docs/en/installation
This snippet demonstrates how to clone the official Melange opam template for ReasonReact, initialize dependencies, and run watch and serve commands for development.
```bash
# clone the repo
git clone https://github.com/melange-re/melange-opam-template my-reason-react-app
# This will initialise the opam switch and install all the dependencies (from both opam and npm)
cd my-reason-react-app && npm run init
# We install native dependencies (melange, dune, reason and reason-react) from opam
# while JavaScript dependencies (react, react-dom, webpack) from npm
# In separate terminals:
npm run watch # It will watch for changes in your Reason/OCaml files and compile them to JavaScript
npm run serve # Serves the application with a local HTTP server
```
--------------------------------
### Install ReasonReact and reason-react-ppx using opam
Source: https://reasonml.github.io/reason-react/blog
Instructions for installing the latest versions of ReasonReact and reason-react-ppx using the opam package manager. This ensures you have the necessary tools for ReasonReact development.
```bash
opam update
opam install reason-react reason-react-ppx
```
--------------------------------
### Build ReasonReact Code with Dune
Source: https://reasonml.github.io/reason-react/docs/en/installation
Commands to build ReasonReact code using Dune. It shows how to build a specific target and how to enable watch mode for automatic recompilation on file changes.
```bash
# "@melange" is an alias created automatically from the target field in the dune file
opam exec -- dune build @melange
# or if you want to watch for changes
opam exec -- dune build @melange --watch
```
--------------------------------
### ReasonReact Simple Counter Example with useState
Source: https://reasonml.github.io/reason-react/docs/en/usestate-hook
A basic example demonstrating the usage of the useState hook to create a counter component in ReasonReact. It shows how to initialize state and update it using buttons.
```reasonml
[@react.component]
let make = (~initialCount) => {
let (count, setCount) = React.useState(_ => initialCount);
{React.string("Count: " ++ Int.to_string(count))}
;
};
```
--------------------------------
### Opam Package Definitions for React Dependencies
Source: https://reasonml.github.io/reason-react/blog/2023/09/13/reason-react-ppx
This example demonstrates how to specify external npm dependencies for React and React-DOM using opam's depexts. This ensures that the correct versions of these libraries are installed when managing project dependencies.
```opam
depexts: [
[ "react" ] {npm-version = "^16.0.0 || ^17.0.0"}
[ "react-dom" ] {npm-version = "^16.0.0 || ^17.0.0"}
]
```
--------------------------------
### ReasonReact useEffect Cleanup Example
Source: https://reasonml.github.io/reason-react/docs/en/useeffect-hook
Demonstrates how to use `useEffect0` in ReasonReact to set up a subscription and clean it up when the component unmounts. This is useful for preventing memory leaks.
```reasonml
[@react.component]
let make = () => {
React.useEffect0(() => {
let id = subscription.subscribe();
/* clean up the subscription */
Some(() => subscription.unsubscribe(id));
});
}
```
--------------------------------
### Install ReasonReact with opam
Source: https://reasonml.github.io/reason-react/blog/2023/06/11/reborn
Installs the latest version of ReasonReact using the opam package manager. This is the first step to adopting ReasonReact in a Melange project.
```bash
opam install reason-react
```
--------------------------------
### ReasonReact ReactDOM Client Rendering Example
Source: https://reasonml.github.io/reason-react/docs/en/dom
Demonstrates how to use ReactDOM.Client.createRoot and ReactDOM.Client.render to render a React element into the DOM using ReasonReact. This replaces the older ReactDOM.render function in React 18. It handles cases where the target element might not be found.
```reasonml
let element = ReactDOM.querySelector("#root");
switch (element) {
| None => Js.log("#root element not found");
| Some(element) => {
let root = ReactDOM.Client.createRoot(element);
ReactDOM.Client.render(, root);
}
}
```
--------------------------------
### ReasonReact Component Example (ReasonML)
Source: https://reasonml.github.io/reason-react/ja
A basic ReasonReact component demonstrating how to define a functional component using the 'react.component' attribute. It takes a 'name' prop and renders a button with a greeting.
```reasonml
[@react.component]
let make = (~name) =>
;
```
--------------------------------
### Basic Greeting Component in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/simple
Demonstrates creating a basic ReasonReact component named 'Greeting' that accepts a 'message' prop and renders it within an h1 tag. It highlights Reason's implicit return, labeled parameters, and type casting with React.string.
```reasonml
/* Greeting.re */
[@react.component]
let make = (~message) =>
{React.string(message)}
;
```
```javascript
/* ... */
/* ... */
```
--------------------------------
### Component with Optional Arguments and Fragment in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/simple
Illustrates a ReasonReact component that accepts an optional 'description' argument. It uses React.Fragment (<>) and demonstrates conditional rendering based on the presence of the description, including the necessity of React.null for None cases.
```reasonml
[@react.component]
let make = (~title, ~description=?)
=>
<>
/* React.Fragment works the same way as in React.js! */
title
/* Handling optional variables where you don't want to render anything */
{
switch (description) {
| Some(description) => {React.string(description)}
/* Since everything is typed, React.null is required */
| None => React.null
}
}
>;
```
--------------------------------
### Configure Dune for Melange Integration
Source: https://reasonml.github.io/reason-react/docs/en/installation
Configures the Dune build system to use Melange for compiling Reason/OCaml code to JavaScript. This involves specifying the Dune language version and enabling the Melange compiler.
```dune
(lang dune 3.8)
(using melange 0.1)
```
--------------------------------
### ReasonReact useReducer Example
Source: https://reasonml.github.io/reason-react/docs/en/usereducer-hook
Demonstrates the useReducer hook in ReasonReact for managing complex state logic. It defines action types, a reducer function, and a React component that utilizes the hook to update state based on user interactions. This approach is preferable to useState for intricate state management and performance optimization.
```reasonml
/* we can create anything as the type for action, here we use a variant with 2 cases. */
type action =
| Increment
| Decrement;
/* `state` could also be anything. In this case, we want an int */
let reducer = (state, action) =>
switch (action) {
| Increment => state + 1
| Decrement => state - 1
};
[@react.component]
let make = (~initialValue=0) => {
let (state, dispatch) = React.useReducer(reducer, initialValue);
state->React.int
;
};
```
--------------------------------
### Basic ReasonReact Component Test with ReactDOMTestUtils
Source: https://reasonml.github.io/reason-react/docs/en/testing
Demonstrates a basic test case for a ReasonReact component using `ReactDOMTestUtils` and an imaginary `TestFramework` binding. It covers setting up a DOM container, rendering a component using `act`, and asserting its presence via DOM querying. This example assumes `TestFramework` provides `describe`, `test`, `beforeEach`, and `afterEach` functions, similar to Jest.
```reason
open ReactDOMTestUtils;
open TestFramework;
// TestFramework isn't a real module, just an imaginary set of bindings
// to a JavaScript testing framework
describe("My basic test", ({test, beforeEach, afterEach}) => {
// Here, we prepare an empty ref that will eventually be
// the root node for our test
let container = ref(None);
// Before each test, creates a new div root
beforeEach(prepareContainer(container));
// After each test, removes the div
afterEach(cleanupContainer(container));
test("can render DOM elements", ({expect}) => {
// The following function gives us the div
let container = getContainer(container);
let root = ReactDOM.Client.createRoot(container);
// Most of the ReactDOMTestUtils API is there
act(() => {
ReactDOM.Client.render(root,
"Hello world!"->React.string
);
});
expect.bool(
container
// We also provide some basic DOM querying utilities
// to ease your tests
->DOM.findBySelectorAndTextContent("div", "Hello world!")
->Option.isSome,
).
toBeTrue();
});
});
```
--------------------------------
### Render ReasonReact Component in Plain JavaScript
Source: https://reasonml.github.io/reason-react/docs/en/intro-example
Shows the equivalent way to render a React component in plain JavaScript, as a comparison to the ReasonML rendering example. This snippet uses standard JavaScript DOM manipulation and ReactDOM.render.
```javascript
/* file: index.js */
let root = document.getElementById("root");
if (root != null) {
ReactDOM.render(, root);
};
```
--------------------------------
### ReasonReact JSX with Children Example
Source: https://reasonml.github.io/reason-react/docs/en/components
Shows how to use the 'ComponentTakesChildren' component in ReasonReact JSX, passing a 'name' prop and providing JSX elements as children. This demonstrates the practical usage of components that handle children.
```reason
{React.string("Effectively the child.")}
```
--------------------------------
### Form Component with Event Handling in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/simple
Shows how to create a form component in ReasonReact, including handling form submission and input elements. It covers underscore prefixing for unused variables, shorthand for event props, and Reason-specific syntax like 'type_' for reserved words and the absence of braces for boolean props.
```reasonml
[@react.component]
let make = () => {
/* unused variables are prefixed with an underscore */
let onSubmit = _event => Js.log("Hello this is a log!");
/* onSubmit=onSubmit turns to just onSubmit */
;
};
```
--------------------------------
### List Rendering Component with Belt in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/simple
Demonstrates rendering a list of items in ReasonReact using the Belt library. It defines a record type for list items and uses Belt.Array.map to transform the items into React list elements, emphasizing the type casting required for arrays with ->React.array.
```reasonml
/* We define the type of the item (this is a record) */
type item = {
id: string,
text: string,
};
[@react.component]
let make = (~items) =>
{
items
->Belt.Array.map(item =>
{React.string(item.text)}
)
/* Since everything is typed, the arrays need to be, too! */
->React.array
}
;
```
--------------------------------
### ReasonReact ReactDOM Hydration Example
Source: https://reasonml.github.io/reason-react/docs/en/dom
Shows how to use ReactDOM.Client.hydrateRoot for hydration in ReasonReact, which is the process of making a static HTML page interactive with React. It renders a React element onto an existing DOM element, typically used for server-rendered applications.
```reasonml
let element = ReactDOM.querySelector("#root");
switch (element) {
| None => Js.log("#root element not found");
| Some(element) => {
/* root is a ReactDOM.Client.root and used to render on top of the existing HTML
with ReactDOM.Client.render or unmount, via ReactDOM.Client.unmount. */
let _root = ReactDOM.Client.hydrateRoot(, element);
();
}
}
```
--------------------------------
### ReasonReact useEffect Conditional Firing Example
Source: https://reasonml.github.io/reason-react/docs/en/useeffect-hook
Illustrates using `useEffect1` in ReasonReact to conditionally fire an effect based on changes in a source value. The effect re-runs only when the specified dependencies change, optimizing performance.
```reasonml
[@react.component]
let make = (~source) => {
React.useEffect1(() => {
let id = subscription.subscribe();
/* clean up the subscription */
Some(() => subscription.unsubscribe(id));
}, [|source|]);
}
```
--------------------------------
### Conditional Rendering Based on URL Hash and Application State
Source: https://reasonml.github.io/reason-react/docs/en/router
An example showcasing how to combine URL hash matching with application state (like user login status) to conditionally render different UI elements or states within a ReasonReact component.
```reason
[@react.component]
let make = () => {
let url = ReasonReactRouter.useUrl();
let nowShowing =
switch (url.hash, MyAppStatus.isUserLoggedIn) {
| ("active", _) => Active
| ("completed", _) => Completed
| ("shared", true) => Shared
| ("shared", false) when isSpecialUser => /* handle this state please */
| ("shared", false) => /* handle this state please */
| _ => All
};
/* ... */
}
```
--------------------------------
### ReasonReact Component with Hooks (useReducer, useEffect0)
Source: https://reasonml.github.io/reason-react/blog/2019/04/10/react-hooks
An example of a ReasonReact component utilizing React Hooks. It demonstrates state management with `React.useReducer` and side effect handling with `React.useEffect0`, including setting up and cleaning up an interval timer.
```reasonml
type action = [ Tick ];
type state = { count: int };
[@react.component]
let make = () => {
let (state, dispatch) = React.useReducer(
(state, action) =>
switch (action) {
| Tick => {count: state.count + 1}
},
{count: 0}
);
React.useEffect0(() => {
let timerId = Js.Global.setInterval(() => dispatch(Tick), 1000);
Some(() => Js.Global.clearInterval(timerId))
});
{ReasonReact.string(string_of_int(state.count))}
;
};
```
--------------------------------
### Define Melange Compilation Target in Dune
Source: https://reasonml.github.io/reason-react/docs/en/installation
Defines a Dune stanza for Melange compilation. It specifies the output target name, the libraries to link against (including reason-react), and the preprocessor extensions to use.
```dune
(melange.emit
(target melange) ; or any target name you want
(libraries reason-react)
(preprocess (pps reason-react-ppx)))
```
--------------------------------
### Invalid GraphQL Query Example with graphql-ppx
Source: https://reasonml.github.io/reason-react/docs/en/graphql-apollo
This snippet shows an example of an invalid GraphQL query that would cause a compile-time error with graphql-ppx. The error occurs because the field 'namee' does not exist on the 'currentUser' type, as defined in the graphql_schema.json.
```reasonml
/* Username.re */
module UserQuery = [%graphql {|
query UserQuery {
currentUser {
namee // ERROR: Unknown field on type currentUser
}
}
|}];
```
--------------------------------
### Configure Dune File for ReasonReact
Source: https://reasonml.github.io/reason-react/blog/2023/09/13/reason-react-ppx
This snippet shows how to configure your dune file to include ReasonReact as a library and reason-react-ppx for preprocessing. Ensure these settings are correctly applied for ReasonReact to function with your project.
```ocaml
(libraries reason-react)
(preprocess (pps reason-react-ppx))
```
--------------------------------
### Render ReasonReact Component in ReasonML App
Source: https://reasonml.github.io/reason-react/docs/en/intro-example
Demonstrates how to render the 'Greeting' ReasonReact component within a ReasonML application's entry point. It uses ReactDOM.render to attach the component to a DOM element. This snippet shows the ReasonML way of rendering.
```reasonml
/* file: Index.re */
switch (ReactDOM.querySelector("#root")) {
| Some(root) => ReactDOM.render(, root)
| None => ()
}
```
--------------------------------
### Passing Components as Props in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/component-as-prop
Demonstrates how to pass components as props in ReasonReact, a common pattern when migrating from ReactJS. It involves defining a callback function that renders the target component with its props.
```reasonml
let bannerCallback = (prop1, prop2) => ;
;
```
--------------------------------
### Matching Routes with Pattern Matching in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/router
Demonstrates how to use Reason's powerful pattern matching to handle different URL structures and extract relevant information for routing logic within a React component.
```reason
let url = ReasonReactRouter.useUrl();
switch (url.path) {
| ["book", id, "edit"] => handleBookEdit(id)
| ["book", id] => getBook(id)
| ["book", id, _] => noSuchBookOperation()
| [] => showMainPage()
| ["shop"] | ["shop", "index"] => showShoppingPage()
| ["shop", ...rest] =>
/* e.g. "shop/cart/10", but let "cart/10" be handled by another function */
nestedMatch(rest)
| _ => showNotFoundPage()
};
```
--------------------------------
### Create and Provide ReasonReact Context
Source: https://reasonml.github.io/reason-react/docs/en/context
This snippet demonstrates how to create a context object using `React.createContext` and then create a provider component for that context. The provider component can be defined either in a separate file or within another module. It uses `React.Context.provider` to create the component.
```reasonml
/** as a separate file: ContextProvider.re */
// 1. The context itself
let themeContext = React.createContext("light");
// 2. The provider
include React.Context; // Adds the makeProps external
let make = React.Context.provider(themeContext);
```
```reasonml
/** or inside any other module */
// 1. The context itself
let themeContext = React.createContext("light");
// 2. The provider component
module ContextProvider = {
include React.Context; // Adds the makeProps external
let make = React.Context.provider(themeContext);
};
```
--------------------------------
### Bind to External JavaScript Context in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/context
This example demonstrates how to bind to a React context defined in an external JavaScript file. It uses `bs.module` to import the context and then uses `React.useContext` to consume its value within a ReasonReact component.
```javascript
/** ComponentThatDefinesTheContext.js */
export const ThemeContext = React.createContext("light");
```
```reasonml
/** ComponentToConsumeTheContext.re */
[@bs.module "ComponentThatDefinesTheContext"]
external themeContext: React.Context.t(string) = "ThemeContext";
[@react.component]
let make = () => {
let theme = React.useContext(themeContext);
theme->React.string
}
```
--------------------------------
### Import Basic Reason File to JavaScript (ReasonReact)
Source: https://reasonml.github.io/reason-react/docs/en/importing-reason-into-js
Demonstrates how to import a basic ReasonML component defined in a `.re` file into a JavaScript file (`.js`). It shows the standard way of importing named exports generated by the BuckleScript compiler.
```reason
/* Greeting.re */
[@react.component]
let make = (~name) => {React.string("Hey " ++ name)} ;
```
```javascript
/* App.js */
import { make as Greeting } from './Greeting.bs'
export default function App() {
return
}
```
--------------------------------
### URL Structure and Matching
Source: https://reasonml.github.io/reason-react/docs/en/router
Defines the structure of the `url` record provided by the router and demonstrates how to match routes using ReasonML's pattern matching.
```APIDOC
## URL Structure and Matching
### URL Record Structure
The `url` record represents the current state of the browser's location, parsed into usable components:
```reason
type url = {
path: list(string),
hash: string,
search: string
};
```
* **`path`**: An array of strings representing the pathname, e.g., `"/book/10/edit"` becomes `["book", "10", "edit"]`.
* **`hash`**: The URL's hash fragment (part after `#`), with the `#` symbol removed.
* **`search`**: The URL's query string (part after `?`), with the `?` symbol removed.
**Example**:
For the URL `www.hello.com/book/10/edit?name=Jane#author`, the `url` record would be:
```reason
{
path: ["book", "10", "edit"],
hash: "author",
search: "name=Jane"
}
```
### Route Matching with Pattern Matching
ReasonML's powerful pattern matching allows for flexible and expressive route handling:
```reason
[@react.component]
let make = () => {
let url = ReasonReactRouter.useUrl();
let view =
switch (url.path) {
| ["book", id, "edit"] => HandleBookEdit(id)
| ["book", id] => GetBook(id)
| ["book", id, _] => NoSuchBookOperation()
| [] => ShowMainPage()
| ["shop"] | ["shop", "index"] => ShowShoppingPage()
| ["shop", ...rest] => NestedShopLogic(rest)
| _ => ShowNotFoundPage()
};
{ReasonReact.string("Current View: ") ++ view}
};
```
This example demonstrates matching exact paths, sub-paths, and using the `...rest` syntax for nested routing logic. You can also combine URL matching with other state, like user login status, using nested switches or `if` conditions within the match cases:
```
--------------------------------
### ReasonReact Component for ReactJS
Source: https://reasonml.github.io/reason-react/docs/en/js-using-reason
This snippet demonstrates how to define a React component using ReasonReact. It takes a 'message' prop and an optional 'extraGreeting' prop. The component renders a 'MyBannerRe' component with a combined message. The generated JavaScript can be imported and used in a ReactJS application.
```reason
/* ReasonReact used by ReactJS */
[@react.component]
let make = (~message, ~extraGreeting=?)
=> {
let greeting =
switch (extraGreeting) {
| None => "How are you?"
| Some(g) => g
};
;
};
```
```javascript
var PageReason = require('path/to/PageReason.js').make;
```
--------------------------------
### ReactJS useState with Event Handling (for comparison)
Source: https://reasonml.github.io/reason-react/docs/en/usestate-hook
Illustrates a common pattern in ReactJS for handling input changes using the useState hook and an onChange event handler.
```javascript
/* App.js */
function App() {
const [name, setName] = React.useState("John");
return (
setName(event.target.value)}
/>
);
}
```
--------------------------------
### Using Apollo Client with graphql-ppx in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/graphql-apollo
This snippet illustrates how to use Apollo Client hooks (useQuery) with a type-safe GraphQL query defined by graphql-ppx in ReasonReact. It shows how to handle different query states (Loading, Data, Error) using Reason's pattern matching and idiomatic variant handling, ensuring both Reason and GraphQL type safety.
```reasonml
/* Username.re */
module UserQuery = [%graphql {|
query UserQuery {
currentUser {
name
}
}
|}];
[@react.component]
let make = () => {
let (currentUserName, _) = ApolloHooks.useQuery(UserQuery.definition);
{
switch(currentUserName) {
| Loading =>
{React.string("Loading...")}
| Data(data) =>
{React.string(data##currentUser##name)}
| NoData
| Error(_) =>
{React.string("Get off my lawn!")}
}
}
}
```
--------------------------------
### Use Spread Component to Add data-* Attributes in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/adding-data-props
This ReasonReact example demonstrates how to use the 'Spread' component to add a 'data-cy' attribute to a div element. The 'Spread' component accepts a 'props' record containing the desired attribute and its value, and then renders the 'children' with these attributes applied.
```reason
[@react.component]
let make = () =>
/* This div will now have the `data-cy` attribute in the DOM! */
;
```
--------------------------------
### Wrap Component Tree with ReasonReact Context Provider
Source: https://reasonml.github.io/reason-react/docs/en/context
This code shows how to use the `ContextProvider` component created previously to wrap a part of the component tree. Any child component within this `ContextProvider` will have access to the context value passed via the `value` prop.
```reasonml
/** App.re */
[@react.component]
let make = () =>
```
--------------------------------
### ReasonReact ReactDOMServer Rendering to String
Source: https://reasonml.github.io/reason-react/docs/en/dom
Illustrates the usage of ReactDOMServer.renderToString from ReasonReact, which is equivalent to React-DOM/server's renderToString. It takes a React element and returns its HTML representation as a string.
```reasonml
/* Example usage of renderToString */
let htmlString = ReactDOMServer.renderToString();
```
--------------------------------
### cloneElement Function in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/clone-element
Demonstrates the usage of the cloneElement function in ReasonReact, which is analogous to ReactJS's cloneElement. It shows how to clone an element and add props, while also warning about the unsafety of the props value and discouraging prop spreading simulation.
```reasonml
let clonedElement = React.cloneElement(, ~props={"payload": 1}, [||]);
```
--------------------------------
### Handling URL Changes Manually
Source: https://reasonml.github.io/reason-react/docs/en/router
Explains how to manually update the URL and trigger the necessary events for the router to detect the changes.
```APIDOC
## Handling URL Changes Manually
### Pushing a New Route
To navigate to a new route programmatically, use the `ReasonReactRouter.push` function:
```reason
ReasonReactRouter.push("/books/10/edit#validated");
```
This function updates the browser's URL using the `History API` (`pushState`) and then dispatches a custom `"popState"` event. This event is what `ReasonReactRouter.useUrl` listens for, ensuring that components re-render with the new URL information.
### Manually Triggering URL Change Detection
If you modify the URL directly using methods other than `ReasonReactRouter.push` (e.g., in an incremental migration scenario), you must manually dispatch a `"popState"` event for the router to recognize the change:
```reason
// After manually changing window.location.href or using pushState
window.dispatchEvent(new Event('popState'));
```
This ensures that the `useUrl` hook and any other watchers are notified of the URL alteration.
```
--------------------------------
### Configure ReasonReact in dune file
Source: https://reasonml.github.io/reason-react/blog/2023/06/11/reborn
Configures the dune build system to include ReasonReact as a library and use the reactjs-jsx-ppx preprocessor for JSX syntax. This is a required step for using ReasonReact.
```dune
(libraries reason-react)
(preprocess (pps react-jsx-ppx))
```
--------------------------------
### Define a ReasonReact Component: Greeting
Source: https://reasonml.github.io/reason-react/docs/en/intro-example
Defines a simple ReasonReact functional component named 'Greeting' that accepts a 'name' prop and renders a button with a personalized greeting. This component is written in ReasonML.
```reasonml
/* file: Greeting.re */
[@react.component]
let make = (~name) => ;
```
--------------------------------
### Basic Render Props in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/render-props
Demonstrates a basic implementation of Render Props in ReasonReact. The `Loader` component accepts a `render` prop, which is a function that returns a React element. This pattern is useful for sharing stateful logic between components.
```reasonreact
[@react.component]
let make = () => {
} />
};
```
```reason
/* Loader.re */
[@react.component]
let make = (~render) => {
{render()}
};
```
--------------------------------
### Define a React Component with ReasonReact
Source: https://reasonml.github.io/reason-react/pt-BR
This snippet demonstrates how to define a basic React component named 'make' using ReasonReact's [@react.component] decorator. The component accepts a 'name' prop and renders a button that displays a greeting. It leverages React.string for rendering text within the button.
```reasonml
[@react.component]
let make = (~name) =>
;
```
```reasonml
[@react.component]
let make = (~name) =>
```
--------------------------------
### ReasonReact Ternary Shortcut
Source: https://reasonml.github.io/reason-react/docs/en/ternary-shortcut
Illustrates the ReasonReact equivalent of ReactJS's ternary shortcut pattern. It shows how to conditionally render elements using the `? : React.null` syntax, which is necessary in ReasonReact unlike the `&&` operator in JavaScript.
```reason
showButton ? : React.null
```
--------------------------------
### ReasonReact useEffect Hook Variations
Source: https://reasonml.github.io/reason-react/docs/en/components
Illustrates the ReasonReact implementation of the useEffect hook, highlighting differences from JavaScript React. It shows how dependency arrays are handled using tuples of varying lengths (useEffect0, useEffect2) and a special case for single dependencies (useEffect1) requiring an array.
```reason
useEffect2(effect, (dep1, dep2))
/* ^^^ -- Note the number matching the dependencies' length */
useEffect0(effect)
/* ^^^ --- Compiles to javascript as `useEffect(effect, [])` */
```
```reason
useEffect1(effect, [|dep|])
```
--------------------------------
### ReasonReact: Inline Styles with ReactDOM.Style.make
Source: https://reasonml.github.io/reason-react/docs/en/style
Demonstrates how to apply inline styles to a React element using ReasonReact's `ReactDOM.Style.make` API. This API provides type-checked style properties, mapping to familiar JavaScript style objects. The returned style is an opaque type.
```reason
```
--------------------------------
### Handle Default Props in JavaScript Component for ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/importing-js-into-reason
Illustrates two scenarios for handling default props in JavaScript components when integrating with ReasonReact. It covers components that already define default props and components where a default needs to be added via a ReasonReact wrapper.
```javascript
function Greeting({
name
}) {
return Hey {name}
};
Greeting.defaultProps = {
name: "John"
};
```
```reason
module Greeting = {
[@mel.module "./Greeting.js"] [@react.component]
external make: (~name: string=?) => React.element = "default";
};
```
```reason
module GreetingJs = {
[@mel.module "./Greeting.js"] [@react.component]
external make: (~name: string) => React.element = "default";
};
module Greeting = {
[@react.component]
let make = (~name="Peter") => ;
};
```
--------------------------------
### Render Component in JavaScript App (using ReasonReact Component)
Source: https://reasonml.github.io/reason-react/docs/en/intro-example
Illustrates how to import and use a ReasonReact component (transpiled to JavaScript) within an existing JavaScript or TypeScript application. It assumes the ReasonReact component exports a function named 'make'.
```javascript
/* file: App.js */
import { make as Greeting } from "./Greeting.js";
export default function App() {
return (
);
}
```
--------------------------------
### Reason React Component Naming Conventions
Source: https://reasonml.github.io/reason-react/docs/en/components
Explains how Reason React components are named in development tools. It covers automatic naming based on module structure and manual naming using `React.setDisplayName`.
```reasonml
/* File.re */
/* will be named `File` in dev tools */
[@react.component]
let make = ...
/* will be named `File$component` in dev tools */
[@react.component]
let component = ...
module Nested = {
/* will be named `File$Nested` in dev tools */
[@react.component]
let make = ...
};
/* If you need a dynamic name for higher-order components or you would like to set your own name you can use `React.setDisplayName(make, "NameThatShouldBeInDevTools");` */
```
--------------------------------
### Import Reason Component as Default Export to JavaScript (ReasonReact)
Source: https://reasonml.github.io/reason-react/docs/en/importing-reason-into-js
Shows how to import a ReasonML component as a default export into a JavaScript file. This involves modifying the ReasonML file to explicitly set the component as the default export using `let default = make;`.
```reason
/* Greeting.re */
[@react.component]
let make = (~name) => {React.string("Hey " ++ name)} ;
/* this sets the named export to default */
let default = make;
```
```javascript
/* App.js */
import Greeting from './Greeting.bs'
export default function App() {
return
}
```
--------------------------------
### Type-Safe GraphQL Queries with graphql-ppx in ReasonReact
Source: https://reasonml.github.io/reason-react/docs/en/graphql-apollo
This snippet demonstrates how to define a type-safe GraphQL query using the %graphql PPX extension in ReasonReact. graphql-ppx validates the query against the schema at compile time, preventing runtime errors. It requires a graphql_schema.json file.
```reasonml
/* Username.re */
module UserQuery = [%graphql {|
query UserQuery {
currentUser {
name
}
}
|}];
```
--------------------------------
### Export Reason React Component to JavaScript
Source: https://reasonml.github.io/reason-react/docs/en/components
Demonstrates how to export a Reason React component to be used in JavaScript. It shows the JavaScript code that requires and renders the component, passing props.
```javascript
const MyComponent = require('./path/to/Component.js').make;
```