-
Notifications
You must be signed in to change notification settings - Fork 347
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master' into create-root-option
- Loading branch information
Showing
24 changed files
with
306 additions
and
1,677 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,106 @@ | ||
# [ReasonReact](https://reasonml.github.io/reason-react/) | ||
# [ReasonReact](https://reasonml.github.io/reason-react/) - ReasonML / BuckleScript bindings for React.js | ||
|
||
[![Chat](https://img.shields.io/discord/235176658175262720.svg?logo=discord&colorb=blue)](https://discord.gg/reasonml) | ||
[![npm version](https://badge.fury.io/js/reason-react.svg)](https://www.npmjs.com/package/reason-react) | ||
![npm](https://img.shields.io/npm/dt/reason-react) | ||
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) | ||
![contributors](https://img.shields.io/github/contributors/reasonml/reason-react) | ||
[![discord](https://img.shields.io/discord/235176658175262720.svg?logo=discord&colorb=blue)](https://discord.gg/reasonml) | ||
[![twitter](https://img.shields.io/twitter/follow/reasonml?style=social)](https://twitter.com/reasonml) | ||
|
||
ReasonReact is a safer, simpler way to build React components. You get a great type system with an even better developer experience. Why choose ReasonReact? Read more [here](https://reasonml.github.io/reason-react/docs/en/what-and-why) | ||
|
||
ReasonReact is just React.js under the hood. This makes it super easy to integrate with your current Next.js, Create React App, JavaScript, Flowtype or TypeScript project. Learn more about getting started [here](https://reasonml.github.io/reason-react/docs/en/installation#adding-reason-to-an-existing-reactjs-project-create-react-app-nextjs-etc) | ||
|
||
> Watch Ricky Vetter's Reason Conf talk, ["Why React is Just Better in Reason"](https://www.youtube.com/watch?v=i9Kr9wuz24g) to learn more about how Facebook & Messenger are using ReasonReact | ||
> Watch Jordan Walke's Reason Conf talk, ["React to the Future"](https://www.youtube.com/watch?v=5fG_lyNuEAw) to learn more about the future of ReasonML and React | ||
## Example | ||
|
||
```reason | ||
/* Greeting.re */ | ||
[@react.component] | ||
let make = (~name) => <h1> {React.string("Hello " ++ name)} </h1> | ||
``` | ||
|
||
in another file: | ||
See all of our examples [here](https://reasonml.github.io/reason-react/docs/en/simple). For a full application, check out [reason-react-hacker-news](https://github.com/reasonml-community/reason-react-hacker-news). | ||
|
||
```reason | ||
ReactDOMRe.renderToElementWithId(<Greeting name="Taylor" />, "root"); | ||
``` | ||
## Getting Started | ||
|
||
For a more in-depth example, see: https://github.com/reasonml-community/reason-react-hacker-news | ||
[BuckleScript](http://bucklescript.github.io/) is how your ReasonML code gets compiled to Javascript. Every project that uses BuckleScript will have a `bsconfig.json` file (the same way you'd have tsconfig.json in a Typescript project) with project specific settings. | ||
|
||
## Quick start | ||
|
||
[BuckleScript](http://bucklescript.github.io/) compiles ReasonML code to JavaScript. You can get it with: | ||
You can install BuckleScript globally or keep it project specific by adding it as a `devDependency`: | ||
|
||
```sh | ||
yarn global add bs-platform | ||
|
||
# or npm | ||
npm install --global bs-platform | ||
``` | ||
|
||
If you install BuckleScript globally, you can quickly generate a ReasonReact project template (similar to `create-react-app`): | ||
|
||
```sh | ||
bsb -init my-react-app -theme react-hooks | ||
cd my-react-app && npm install && npm start | ||
|
||
# in another tab | ||
npm run server | ||
``` | ||
|
||
If you're interested in adding ReasonReact to your current project, it's a simple 2 step process: | ||
|
||
``` | ||
yarn add bs-platform --dev --exact | ||
# or npm | ||
npm install bs-platform -D -S | ||
``` | ||
|
||
Add the appropriate script tags to package.json: | ||
|
||
```json | ||
"scripts": { | ||
"re:build": "bsb -make-world -clean-world", | ||
"re:watch": "bsb -make-world -clean-world -w" | ||
} | ||
``` | ||
|
||
Copy the `bsconfig.json` file from our docs located [here](https://reasonml.github.io/reason-react/docs/en/installation#adding-reason-to-an-existing-reactjs-project-create-react-app-nextjs-etc) | ||
|
||
Then add some files somewhere (don't forget to change `bsconfig.json`, if needed). | ||
|
||
## Using Your Favorite Javascript Libraries | ||
|
||
The same way that TypeScript has `type annotations`, we have `bindings`. Bindings are libraries that allow you to import a popular project (like lodash) or to import your own local file. ReasonReact is in fact an example of a binding! | ||
|
||
## Documentation | ||
|
||
See https://reasonml.github.io/reason-react/ | ||
See [https://reasonml.github.io/reason-react](https://reasonml.github.io/reason-react) | ||
|
||
## Contribute | ||
|
||
We welcome all contributors! Anything from docs to issues to pull requests. Please help us :smile: | ||
|
||
```sh | ||
git clone https://github.com/reasonml/reason-react.git | ||
cd reason-react | ||
npm install | ||
npm start | ||
``` | ||
|
||
Then add some files somewhere (don't forget to change `bsconfig.json`, if needed). | ||
|
||
See the README inside `src` for more info! | ||
|
||
## Editor Support | ||
|
||
Looking for syntax highlighting for your favorite editor? Check out [ReasonML Editor Plugins](https://reasonml.github.io/docs/en/editor-plugins) | ||
|
||
## Friends of ReasonReact | ||
|
||
- [genType](https://github.com/cristianoc/genType) - genType automatically generates bindings for your TypeScript / vanilla JS code. | ||
- [reason-react-native](https://github.com/reason-react-native/reason-react-native) - ReasonML / Bucklescript bindings for React Native. Allows you to use Reason to build an iOS, Android or Web app! | ||
- [reasonml.org](https://reasonml.org/) - An effort by the Reason Association to improve documentation for ReasonML & BuckleScript | ||
- [redex.github.io](https://redex.github.io/) - Find bindings for your favorite libraries here | ||
- [ReasonTown Podcast](https://anchor.fm/reason-town) - ReasonML Podcast | ||
- [ReasonConf Youtube](https://www.youtube.com/channel/UCtFP_Hn5nIbZY4Xi47qfHhw/videos) Reason Conf on Youtube |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
/* This is the BuckleScript configuration file. Note that this is a comment; | ||
BuckleScript comes with a JSON parser that supports comments and trailing | ||
comma. If this screws with your editor highlighting, please tell us by filing | ||
an issue! */ | ||
{ | ||
"name" : "reason-react", | ||
"name": "reason-react", | ||
"sources": "src", | ||
"package-specs": [{ "module": "es6", "in-source": true }], | ||
"suffix": ".bs.js", | ||
"refmt": 3, | ||
"bsc-flags": ["-bs-no-version-header"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
--- | ||
title: Styling: Tailwind CSS | ||
--- | ||
|
||
[Tailwind CSS](https://tailwindcss.com) is a new CSS framework that is rapidly | ||
growing in popularity. It's completely customizable and lightweight, making it | ||
a perfect companion to React. If you're not familiar with Tailwind, we recommend | ||
checking out [their docs](https://tailwindcss.com/#what-is-tailwind) for | ||
a gentle introduction before moving forward. | ||
|
||
## Setting up Tailwind | ||
|
||
Now let's see how we can use Tailwind within ReasonReact and start building an | ||
app! | ||
|
||
First, you'll need to create a new ReasonReact project -- we recommend [this | ||
template](https://github.com/bodhish/create-reason-react-tailwind) (select the | ||
`tailwind-starter` option) which has Tailwind set up out of the box. Once you've | ||
installed the dependencies with `yarn install` or `npm install`, you should be | ||
ready to go. | ||
|
||
Let's see an example of a React component using Tailwind: | ||
|
||
```reason | ||
[@react.component] | ||
let make = () => | ||
<div className="h-screen flex justify-center items-center"> | ||
<div className="max-w-sm rounded overflow-hidden shadow-lg p-4"> | ||
<img className="w-full" src=logo alt="Sunset in the mountains" /> | ||
<div className="px-6 py-4"> | ||
<div className="font-bold text-xl mb-2"> {React.string("Tailwind")} </div> | ||
<p className="text-gray-700 text-base"> | ||
{React.string("A reason react starter with tailwind")} | ||
</p> | ||
</div> | ||
</div> | ||
</div>; | ||
``` | ||
|
||
which gives us the following UI: | ||
|
||
<img src="/reason-react/img/tailwind-example.png"> | ||
|
||
## tailwind-ppx | ||
|
||
Often times when you're writing with Tailwind and ReasonReact, you may find | ||
yourself wondering why the UI isn't working like it should, only to find out you | ||
had a typo in a class name. For example, | ||
|
||
```reason | ||
<div className="flex flex-ro"> | ||
... | ||
</div> | ||
``` | ||
|
||
Wouldn't it be nice to get some validation _while_ you're writing the Tailwind | ||
classes? Better yet, how about preventing your code from even compiling if the | ||
classes aren't correct? Well, enter | ||
[`tailwind-ppx`](https://github.com/dylanirlbeck/tailwind-ppx): a compile-time | ||
validator for Tailwind CSS. Using this PPX, you can get immediate compiler | ||
errors if you happen to misspell class names, along with a nice suggestion of | ||
what you may have meant to write! | ||
|
||
```reason | ||
<div className=[%tw "flex flex-ro"]> /* ERROR: Class name not found: flex-ro. Did you mean flex-row? */ | ||
... | ||
</div> | ||
``` | ||
|
||
Moreover, in a large codebase where components may have many class names, you | ||
may find yourself duplicating some class names. `tailwind-ppx` solves this | ||
issue, too! | ||
|
||
```reason | ||
<div className=[%tw "flex flex-row mt-2 pb-3 flex"]> /* ERROR: Duplicate class name: flex */ | ||
... | ||
</div> | ||
``` | ||
|
||
Wrapping the class names in a PPX allows for some powerful integrations with | ||
Tailwind in addition to validation. For more information, check out | ||
`tailwind-ppx`'s [other features](https://github.com/dylanirlbeck/tailwind-ppx#features) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
--- | ||
title: Using Event Values With useState | ||
--- | ||
|
||
In ReactJS, it's common to update a component's state based on an event's | ||
value. Because ReasonReact's `useState` is slightly different than ReactJS, | ||
directly translating JavaScript components to Reason can lead to a common bug. | ||
|
||
```js | ||
/* App.js */ | ||
function App() { | ||
const [name, setName] = React.useState("John"); | ||
return ( | ||
<input | ||
type="text" | ||
value={name} | ||
onChange={(event) => setName(event.target.value)} | ||
/> | ||
); | ||
} | ||
``` | ||
|
||
If we convert this component to reason, we may attempt to write this: | ||
|
||
```reason | ||
/* App.re */ | ||
/* WRONG! Don't do this! */ | ||
[@react.component] | ||
let make = () => { | ||
let (name, setName) = React.useState(() => "John"); | ||
<input | ||
type_="text" | ||
value={name} | ||
onChange={event => setName(_ => ReactEvent.Form.target(event)##value) | ||
/>; | ||
}; | ||
``` | ||
|
||
Can you spot the bug? | ||
|
||
In the Reason version, the `onChange` callback won't correctly update the state. | ||
This happens because the callback passed to `setName` is run *after* the `event` | ||
variable is cleaned up by React, so the `value` field won't exist when it's | ||
needed. | ||
|
||
This isn't actually any different than how events and `useState` hooks work in | ||
ReactJS when you choose to use a callback with `setName`. The only difference | ||
is that ReasonReact enforces that we always use callbacks. | ||
|
||
## Solution | ||
|
||
Fortunately, fixing this bug is simple: | ||
|
||
```reason | ||
/* App.re */ | ||
/* CORRECT! This code is bug-free. 👍 */ | ||
[@react.component] | ||
let make = () => { | ||
let (name, setName) = React.useState(() => "John"); | ||
<input | ||
type_="text" | ||
value={name} | ||
onChange={ | ||
event => { | ||
let value = ReactEvent.Form.target(event)##value; | ||
setName(_ => value) | ||
} | ||
} | ||
/>; | ||
}; | ||
``` | ||
|
||
The key is to extract the `value` from the `event` *before* we send it to | ||
`setName`. Even if React cleans up the event, we don't lose access to the | ||
value we need. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.