极速开发 React — Reason 2

Speed_Racer_promotional_image.jpg

现在是速度至上的时代,我们必须以一敌百。才能立于不败之地。

FCJG300-0043.jpg

面对越来越复杂的业务逻辑,我们只能全速向前冲,这一切都需要有技术作为保障。所以我们需要选择一个能够实现快速开发的技术。
th.jpg

reason react 网址
个人选择并且推荐使用 reason 来开发
极速开发 React — Reason 1

  • 更安全,更简洁的方式去构建 React 组件
  • 完全兼容 JSX
  • 类型安全兼容 javascript 编写的组件
  • 用于一种全新的表述型 API 来描述状态管理
rr_001.JPG

搭建项目

npm install -g bs-platform
bsb -init my-react-app -theme react
cd my-react-app && npm install && npm start
npm run webpack

创建 index.html

我们将架构默认的工程文件都删除,自己来写一个列表的 demo。先创建一个 index.html。

  • 引入 Index.js 最终 webpack 打包后会引用 index.js
  • id 为 app 的 div,我们的应用都写在这个 div 下面
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Zidea ReasonReact Examples</title>
</head>
<body>
  <div id="app"></div>
  <script src="Index.js"></script>
</body>
</html>

然后创建 re 结尾的 reason 文件

ReactDOMRe.renderToElementWithId(<TutListComponent />, "app");

我们这里可能需要使用 bs-json 和 bs-fetch,我们可以用 npm 来安装一下这两个库,或者说是 reason 的模块。然后需要 bsconfig 文件添加依赖,这样我们就可以在工程中使用这两模块。

 "bs-dependencies": [
    "reason-react",
    "@glennsl/bs-json",
    "bs-fetch"
  ],

我这里用 python flask 写了一个服务,返回值为


rr_002.JPG
  • 我们先定义一个数据结构,用 type 定义 tut 类型 string
    我们可以定义 type 定义的数据类型,reason 是一种类型的语言,这对没有类型的 javascript 是一个强大的支持。
type tut = {title:string, body:string}

我们这里根据官网的 demo 就先简单地定义为 string

type tut = string;
  • reason react 给我们提供两种创建组件模板
  1. statelessComponent
  2. reducerComponent
    这里我们创建 reducerComponent 类型组件
  • 创建 state 状态 这也是 ocaml 的语法,应该算是类型匹配吧,有了这个就可以保证我们在做分支语句不会漏掉某些可能性。action 定义方式也是一样,有关 action 和 state 如果大家还没有接触过可以看一看 redux,以后我会分享的。
type state = 
    | Loading
    | Loaded(array(tut))
    | Error;
  • 定义模块 Decode
    我们可以在模块定中定义类型和方法,这里我们定义了一个 tuts 的方法,用于解析服务端返回的数据,然后我们使用 Json 模块的 Decode 方法,这个 Json 模块需要我们手动引用一下。|> 如果用过 linux 的脚本或者写过 powershell 的程序员可能不会陌生,这是链式操作。我们接受返回 json -> 然后获取 messages 字段的值类型为 string 的数组 -> 然后对数组进行映射。
module Decode = {
    let tuts = json: array(string) =>
        Json.Decode.(
            json |> field("messages",array(string)) |> Array.map(_, tut => tut)
        )
}


- **make**
是让我们在编译时生产 component 的方法。

  • 初始化我们 state
 initialState: _state => Loading,

然后就是 reducer 这纯函数,最近然后 mvi 模式,再次开始研究 reducer,reduce 我还是在学习 redux + react + rxjs 时学习过,为了理解也花费不少精力。这里简单介绍一下,毕竟 reduce 不是我们今天的重点。reduce 是一个纯函数,接受 action(动作)返回一个新的 state。然后我们 reducer 中根据 action 进行分支更新我们状态。这里我发现没有用引入 redux 却做了 redux 事情,代码表意也挺好,给 reason 一个赞。

  • 在说一下 Promise ,对于了解 es6 前端 promise 应该不是很陌生,这里同样使用管道符来进行处理。
Js.Promise.(
                            Fetch.fetch("http://localhost:4600/get_tuts")
                            |> then_(Fetch.Response.json)
                            |> then_(json =>
                                json
                                |> Decode.tuts
                                |> (tuts => self.send(TutsFetched(tuts)))
                                |> resolve
                            )
                            |> catch(_err => 
                                    Js.Promise.resolve(self.send(TutsFailedToFetch))
                                )
                            |> ignore
                        )
  • 最后就是 render 函数来渲染我们组件到界面
type tut = string;

type state = 
    | Loading
    | Loaded(array(tut))
    | Error;
type action = 
    | TutsFetch
    | TutsFetched(array(tut))
    | TutsFailedToFetch;

module Decode = {
    let tuts = json: array(string) =>
        Json.Decode.(
            json |> field("messages",array(string)) |> Array.map(_, tut => tut)
        )
}



let component = ReasonReact.reducerComponent("TutListComponent");

let make = _children => {
    ...component,
    initialState: _state => Loading,
    reducer: (action, _state) =>
        switch (action) {
        | TutsFetch => 
            ReasonReact.UpdateWithSideEffects(
                Loading,
                (
                    self =>
                        Js.Promise.(
                            Fetch.fetch("http://localhost:4600/get_tuts")
                            |> then_(Fetch.Response.json)
                            |> then_(json =>
                                json
                                |> Decode.tuts
                                |> (tuts => self.send(TutsFetched(tuts)))
                                |> resolve
                            )
                            |> catch(_err => 
                                    Js.Promise.resolve(self.send(TutsFailedToFetch))
                                )
                            |> ignore
                        )
                ),
            )
        | TutsFetched(tuts) => ReasonReact.Update(Loaded(tuts))
        | TutsFailedToFetch => ReasonReact.Update(Error)
    },
    didMount: self => self.send(TutsFetch),
    render: self =>
    switch (self.state) {
    | Error => <div> (ReasonReact.string("An error occurred!")) </div>
    | Loading => <div> (ReasonReact.string("Loading...")) </div>
    | Loaded(tuts) =>
      <div>
        <h1> (ReasonReact.string("tuts")) </h1>
        <p> (ReasonReact.string("Source: ")) </p>
        <a href=""></a>
        <ul>
          (
            Array.map(tuts, tut =>
              <li key=tut> (ReasonReact.string(tut)) </li>
            )
            |> ReasonReact.array
          )
        </ul>
      </div>
    },
};
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容