
Margarita
Krutikova
Kyrylo
Yakymenko
Agenda
- What is Reason?
- Why should we care?
- Language features
- The new ReasonReact hooks API
- 
DEMO
	- React components in Reason
- useState, useReducer
- Routing
- GraphQL with reason-apollo-hooks
- Stuff we've built with Reason
 
- Summary
a functional programming language
React bindings for ReasonML
compiles ReasonML to JavaScript

syntactic extension of
Allows writing React applications in ReasonML

"Babel" for ReasonML
Why?
- 
Statically typed, functional and pragmatic
 best of two worlds




Constraints
Flexibility
Guarantees




"Sweet Spot of Pragmatism"
Why?
- 
Statically typed, functional and pragmatic
 best of two worlds
- Powered by Facebook (used in production)
Why?
- 
Statically typed, functional and pragmatic
 best of two worlds
- Powered by Facebook
- Fun fact: Jordan Walke, the creator of React is now working on Reason

Why?
- 
Statically typed, functional and pragmatic
 best of two worlds
- Powered by Facebook
- Fun fact: Jordan Walke, the creator of React is now working on Reason
- Expressive type system, strong type inference
- Extremely fast builds

Why?
- 
Statically typed, functional and pragmatic
 best of two worlds
- Powered by Facebook
- Fun fact: Jordan Walke, the creator of React is now working on Reason
- Expressive type system, strong type inference
- Extremely fast builds
- Access to the whole JS ecosystem (npm)
- Incremental adoption possible
Syntax
- reminds of Javascript
    let multiply = (a, b) => a * b;
    let welcome = name => "Welcome, " ++ name;
        
    let veggies = ["pumpkin", "kale", "broccoli"];
The cool stuff
- 
	Variants + pattern matching

      type response = 
       | Fetching
       | Error(string)
       | Success(user);
Variant

      switch (response) {
       | Fetching => <Spinner />
       | Error(err) => <Error err />
       | Success(user) => <MyPages user />
      }     
     
     
                type Response = {
                  error: string | null,
                  user: User | null,
                  isLoading: boolean
                }
                if (response.loading) {
                 ...
                }
                if (response.error) {
                 ...
                }
                if (response.user) {
                  ...
                }Typescript





Pattern Matching (JS)
switch (action.type) {
  case "FETCHING":
    return "Fetching...";
    
  case "ERROR":
    if (action.errorCode === 401) {
      return "Unauthorized!";
    }
    if (action.errorCode === 404) {
      return "Not found!";
    }
    return "Unknown error...";
    
  case "SUCCESS":
    return action.data;
}Pattern Matching (Reason)
switch (action) {
  | Fetching => "Fetching..."
  | Error(401) => "Unauthorized!"
  | Error(404) => "Not found!"
  | Error(_) => "Unknown error..."
  | Success(data) => data
}Pattern Matching (routing)
let url = ReasonReactRouter.useUrl();
switch (url.path) {
  | ["cart"] => <CartPage />
  | ["products", "sale"] => <CampaignPage />
  | ["products", id] => <ProductPage id />
  | _ => <NotFound />
};Built-in router: ReasonReactRouter
The cool stuff
- 
	Variants + pattern matching
- 
	Option

Option
type option('a) = None | Some('a)
- 
	No null / undefined 
- 
	Safe alternative to concept of nonexistent value 
let maybeInt = Some(45);
let maybeUser = Some({ name: "John" });Option
      let maybeUser = Some({ name: "John" });
      
      switch (maybeUser) {
        | Some(user) => "Hello, " + user.name
        | None => "Please, log in"
      };
❌ Cannot read property of 'undefined',
'undefined' is not an object, null is not an object,
‘undefined’ is not a function (c) Javascript
Get the value out of it?
The cool stuff
- 
	Variants + pattern matching
- 
	Option
- 
	Records

Records
- 
	Fixed fields 
- 
	Immutable 
- 
	Very fast 
- 
	Compile to arrays 🤯 
Similar to JS objects, but

Records
type user = { name: string, age: int };
let john = { 
  name: "John", 
  age: 42 
};john.name = "Bob";

let bob = { ...john, name: "Bob" };The cool stuff
- 
	Variants + pattern matching
- 
	Option
- 
	Records
- 
	Module system

Module system
- 
	No import necessary 
- 
	Module name is file name 
- 
	Compiler automatically searches for modules 
- 
	Requirement: unique file names per project 
- 
	Folder structure doesn't matter 

Module system
import { Button } from '../../commmon/Button'
import { makePretty } from '../../../utils'
<Button text={Utils.makePretty(ugly)} />

* Button.re and Utils.re are somewhere in the project
The cool stuff
- 
	Variants + pattern matching
- 
	Option
- 
	Records
- 
	Module system
- 
	Built-in formater

Automatic code formatting
JS/TS: Prettier
- prettier-vscode
- prettier-eslint
- eslint-plugin-prettier
- eslint-config-prettier
- (tslint-config-prettier)
- .prettierrc
- .eslintrc
- settings.json -> prettier settings
reason-language-server
+
refmt
ReasonML


ReasonReact
- Reason bindings for React
- Allows writing React components to whole React applications in ReasonML
- Supports React hooks as of v0.7.0!
- Future of React? 🤔
DEMO

- Variants, powerful pattern matching
- Functional language, but pragmatic
 (has mutation, side effects)
- Expressive, proven type system with strong type inference
- Compilation speed
- Interop with other libs - use anything on npm!
- Possibility to compile to native code
- Driven by Facebook
Summary
- Hasn't reached a critical mass yet
- Still "raw"
- 
	Tooling not on par with JS/TS 
- 
	Sometimes tricky to find up-to-date libraries/bindings 
Disadvantages
Adoption Strategies
No need to go all in from the start
- Start with individual components
- Start with logic/functions
- Start with API decoders
Questions?
Example apps built with
ReasonReact
Hasura GraphQL
Netlify
MaterialUI
CSS-in-JS







Reason Gothenburg Meetup
ReasonReact
By Kyrylo Yakymenko
ReasonReact
- 511
 
   
   
  