Pro Yearly is on sale from $80 to $50! »

Get started with Reason

Get started with Reason

We will kick off with the basics and then quickly go into how to leverage features like variant types and pattern matching to make impossible states impossible. After you gained some knowledge about the basics the course will dig even further into ReasonReact.

Afcee4ad6e383e26799ff05681d1a2a5?s=128

Nikolaus Graf

April 26, 2018
Tweet

Transcript

  1. None
  2. None
  3. JavaScript developer friendly syntax

  4. let meaningOfLife = 41 + 1;

  5. let add = (x, y) => x + y; add(2,

    2); add(41, 1);
  6. let fruits = ["Apple", "Orange"];

  7. if (true) { print_string("Hello World!"); };

  8. OCaml semantics

  9. Reason Syntax OCaml Syntax OCaml AST

  10. Records

  11. let jane = {name: "Jane", age: 40};

  12. let jane = {name: "Jane", age: 40};

  13. type person = { name: string, age: int, }; let

    jane = {name: "Jane", age: 40};
  14. type person = { name: string, age: int, }; let

    jane = {name: "Jane", age: 40}; let tim = {...jane, name: "Tim"};
  15. Compiles to JavaScript

  16. Reason Syntax OCaml Syntax OCaml AST JavaScript BuckleScript

  17. Reason Syntax OCaml Syntax OCaml AST Native Code JavaScript BuckleScript

  18. Fromatter

  19. Reason Syntax OCaml Syntax OCaml AST Native Code JavaScript BuckleScript

  20. Reason Syntax OCaml Syntax OCaml AST Native Code JavaScript refmt

    BuckleScript
  21. Statically Typed Language

  22. None
  23. Why yet another one?

  24. None
  25. const pieces = [ { kind: "king", color: "black", position:

    [3, 4] }, { kind: "pawn", color: "black", position: [4, 2] }, { kind: "knight", color: "white", position: [3, 3] } ]; JavaScript
  26. interface Piece { kind: string; color: string; position: number[]; }

    const pieces = [ { kind: "king", color: "black", position: [3, 4] }, { kind: "pawn", color: "black", position: [4, 2] }, { kind: "knight", color: "white", position: [3, 3] } ]; const getKinds = (pieces: Piece[]) => pieces.map(piece => piece.kind); TypeScript
  27. interface Piece { kind: string; color: string; position: number[]; }

    const pieces = [ { kind: "king", color: "black", position: [3, 4] }, { kind: "pawn", color: "black", position: [4, 2] }, { kind: "knight", color: "white", position: [3, 3] } ]; const getKinds = (pieces: Piece[]) => pieces.map(piece => piece.kind); TypeScript
  28. type piece = { kind: string, color: string, position: (int,

    int), }; let pieces = [ {kind: "king", color: "black", position: (3, 4)}, {kind: "pawn", color: "black", position: (4, 2)}, {kind: "knight", color: "white", position: (3, 3)}, ]; let getKinds = pieces => List.map(item => item.kind, pieces); Reason
  29. Variants

  30. type direction = | Up | Down | Left |

    Right;
  31. type direction = | Up | Down | Left |

    Right; let move = Left;
  32. type direction = | Up(int) | Down(int) | Left(int) |

    Right(int); let move = Left(2);
  33. type data = {names: list(string)}; type request = | Loading

    | Error(int) | Success(data);
  34. type color = Black | White; type kind = Queen

    | King | Rook | Bishop | Knight | Pawn; type piece = { color, kind, position: (int, int), }; let pieces = [ {kind: King, color: Black, position: (3, 4)}, {kind: Pawn, color: Black, position: (4, 2)}, {kind: Knight, color: White, position: (3, 3)}, ];
  35. type color = Black | White; type kind = Queen

    | King | Rook | Bishop | Knight | Pawn; type piece = { color, kind, position: (int, int), }; let pieces = [ {kind: King, color: Black, position: (3, 4)}, {kind: Pawn, color: Black, position: (4, 2)}, {kind: Knight, color: White, position: (3, 3)}, ];
  36. type color = Black | White; type kind = Queen

    | King | Rook | Bishop | Knight | Pawn; type piece = { color, kind, position: (int, int), }; let pieces = [ {kind: King, color: Black, position: (3, 4)}, {kind: Pawn, color: Black, position: (4, 2)}, {kind: Knight, color: White, position: (3, 3)}, ];
  37. Pattern Matching

  38. switch (<value>) { | <pattern1> => <case1> | <pattern2> =>

    <case2> | ... };
  39. switch (1) { | 0 => "off" | 1 =>

    "on" | _ => "off" };
  40. let displayText = switch (1) { | 0 => "off"

    | 1 => "on" | _ => "off" };
  41. type data = {names: list(string)}; type request = | Loading

    | Error(int) | Success(data); let ui = switch (Loading) { | Loading => "Loading ..." | Error(code) => "Something went wrong. Error: " ++ string_of_int(code) | Success(data) => List.fold_left((a, b) => a ++ b, "Names:", data.names) };
  42. type data = {names: list(string)}; type request = | Loading

    | Error(int) | Success(data); let ui = switch (Loading) { | Loading => "Loading ..." | Error(401) => "You aren’t authenticated." | Error(code) => "Something went wrong. Error: " ++ string_of_int(code) | Success(data) => List.fold_left((a, b) => a ++ b, "Names:", data.names) };
  43. type data = {names: list(string)}; type request = | Loading

    | Error(int) | Success(data); let ui = switch (Loading) { | Loading => "Loading ..." | Error(401 | 402) => "You aren’t authenticated." | Error(code) => "Something went wrong. Error: " ++ string_of_int(code) | Success(data) => List.fold_left((a, b) => a ++ b, "Names:", data.names) };
  44. None
  45. – Tony Hoare “I call it my billion-dollar mistake …”

  46. None
  47. None
  48. Lesson I Don’t implement anything just because it’s easy!

  49. Lesson II Null is BAD!

  50. null; // doesn't exist!

  51. Option

  52. let foo = None; let foo = Some(42); let foo

    = Some([1, 2, 3]); let foo = Some("Hello World!");
  53. let foo = None; let foo = Some(42); let foo

    = Some([1, 2, 3]); let foo = Some("Hello World!"); switch (foo) { | None => "Sadly I don't know." | Some(value) => "It's " ++ value };
  54. Functions

  55. let add = (x, y) => x + y; add(2,

    2); add(41, 1);
  56. let name = (~firstName, ~lastName) => firstName ++ " "

    ++ lastName; /* Jane Doe */ name(~firstName="Jane", ~lastName="Doe"); /* Jane Doe */ name(~lastName="Doe", ~firstName="Jane");
  57. ReasonReact

  58. Stateless Component let component = ReasonReact.statelessComponent("Greeting"); let make = (_children)

    => { ...component, render: _self => <h1>(ReasonReact.string("Hello"))</h1>, }; ReactDOMRe.renderToElementWithId(<Greeting />, "root"); Greeting.re App.re
  59. Props let component = ReasonReact.statelessComponent("Greeting"); let make = (~name, _children)

    => { ...component, render: _self => <h1>(ReasonReact.string(“Hello " ++ name))</h1>, }; ReactDOMRe.renderToElementWithId(<Greeting name="Helsinki" />, "root"); Greeting.re App.re
  60. Props let component = ReasonReact.statelessComponent("Greeting"); let make = (~name, _children)

    => { ...component, render: _self => <h1>(ReasonReact.string("Hello " ++ name))</h1>, }; ReactDOMRe.renderToElementWithId(<Greeting name="Helsinki" />, "root"); Greeting.re App.re
  61. Props let component = ReasonReact.statelessComponent("Greeting"); let make = (~name, _children)

    => { ...component, render: _self => <h1>(ReasonReact.string("Hello " ++ name))</h1>, }; ReactDOMRe.renderToElementWithId(<Greeting name="Helsinki" />, "root"); Greeting.re App.re
  62. None
  63. type state = {count: int};

  64. type state = {count: int}; type action = | Add(int)

    | Reset;
  65. type state = {count: int}; type action = | Add(int)

    | Reset; let s = ReasonReact.string;
  66. type state = {count: int}; type action = | Add(int)

    | Reset; let s = ReasonReact.string; let component = ReasonReact.reducerComponent("Counter");
  67. type state = {count: int}; type action = | Add(int)

    | Reset; let s = ReasonReact.string; let component = ReasonReact.reducerComponent("Counter"); let make = _children => { ...component, initialState: () => {count: 0},
  68. type state = {count: int}; type action = | Add(int)

    | Reset; let s = ReasonReact.string; let component = ReasonReact.reducerComponent("Counter"); let make = _children => { ...component, initialState: () => {count: 0}, reducer: (action, state) => switch (action) { | Add(value) => ReasonReact.Update({count: state.count + value}) | Reset => ReasonReact.Update({count: 0}) },
  69. type state = {count: int}; type action = | Add(int)

    | Reset; let s = ReasonReact.string; let component = ReasonReact.reducerComponent("Counter"); let make = _children => { ...component, initialState: () => {count: 0}, reducer: (action, state) => switch (action) { | Add(value) => ReasonReact.Update({count: state.count + value}) | Reset => ReasonReact.Update({count: 0}) }, render: self => <div> (s(string_of_int(self.state.count)))
  70. let s = ReasonReact.string; let component = ReasonReact.reducerComponent("Counter"); let make

    = _children => { ...component, initialState: () => {count: 0}, reducer: (action, state) => switch (action) { | Add(value) => ReasonReact.Update({count: state.count + value}) | Reset => ReasonReact.Update({count: 0}) }, render: self => <div> (s(string_of_int(self.state.count))) <button onClick=(_event => self.send(Add(1)))> (s(“Add")) </button> <button onClick=(_event => self.send(Add(2)))> (s("Add 2")) </button> <button onClick=(_event => self.send(Reset))> (s("Reset")) </button> </div>, };
  71. None
  72. Manage your State with GraphQL

  73. Interop with JavaScript

  74. BuckleScript allows us to write bindings ReasonReact - wrapJsForReason -

    wrapReasonForJs
  75. [@bs.module "rebass"] external jsArrow : ReasonReact.reactClass = "Arrow"; let make

    = (~direction: string, children) => ReasonReact.wrapJsForReason( ~reactClass=jsArrow, ~props={"direction": direction}, children, );
  76. <Arrow direction="down" />

  77. <Arrow direction="left" />

  78. <Arrow direction="notRight"/>

  79. None
  80. Variants to the rescue!

  81. [@bs.module "rebass"] external jsArrow : ReasonReact.reactClass = "Arrow"; type direction

    = | Up | Down; let make = (~direction, children) => { let directionString = switch (direction) { | Up => "up" | Down => "down" }; ReasonReact.wrapJsForReason( ~reactClass=jsArrow, ~props={"direction": directionString}, children, ); };
  82. <Arrow direction=Arrow.Down />;

  83. <Arrow direction=Arrow.Left />;

  84. <Arrow direction=Arrow.Left />;

  85. So what now?

  86. Don’t be that person

  87. Time Innovation React Ecosystem

  88. Time Innovation React Ecosystem Reason Ecosystem

  89. Day 1: Workshop Day 2: Talks Day 3: Hackathon

  90. The End