點燈坊

失くすものさえない今が強くなるチャンスよ

使用 ap 將 Value 平行寫入 State

Sam Xiao's Avatar 2021-07-09

若想將 API 回傳 Value 寫入多個 State,可使用 ap 平行寫入。

Version

Vue 3.0.11
Sanctuary 3.1.0
Fluture 14.0.0

pipe

ap000

按下 Get Book,將相同資料寫入 titletitle_ state 顯示。

<template lang='pug'>
button(@click='onClick') Get Book
div {{ title }} / {{ title_ }}
</template>

<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import S from 'sanctuary'
import { error } from 'wink-fp'
import { fork, mapRej } from 'fluture'
import getBook from '/src/api/getBook_'

let { props, unchecked: { pipe, map }} = S

let title = ref ('')
let title_ = ref ('')

let effect = pipe ([
  write (title),
  write (title_)
])

let onClick = pipe ([
  getBook (1),
  map (props (['data', 'title'])),
  mapRej (props (['response', 'data', 'error'])),
  fork (error) (effect)
])
</script>

25 行

let onClick = pipe ([
  getBook (1),
  map (props (['data', 'title'])),
  mapRej (props (['response', 'data', 'error'])),
  fork (error) (effect)
])

使用 pipe 組合 onClick

  • getBook (1):將 id 傳入 getBook 回傳 Future
  • map (props (['data', 'title'])):在 Resolved 內取得 data.title
  • mapRej (props (['response', 'data', 'error'])):在 Rejected 內取得 response.date.error
  • fork (error) (effect):從 Future 內處理 Rejected 與 Resolved

20 行

let effect = pipe ([
  write (title),
  write (title_)
])

使用 pipe 組合 effect

  • write (title):寫入 title state 並回傳 value
  • write (title_):再次寫入 title_ state

由於 write 會將原 value 回傳,故也可將 pipe 多次組合 write 實現

ap

<template lang='pug'>
button(@click='onClick') Get Book
div {{ title }} / {{ title_ }}
</template>

<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import S from 'sanctuary'
import { error } from 'wink-fp'
import { fork, mapRej } from 'fluture'
import getBook from '/src/api/getBook_'

let { ap, props, of, unchecked: { pipe, map }} = S

let title = ref ('')
let title_ = ref ('')

let onClick = pipe ([
  getBook (1),
  map (props (['data', 'title'])),
  map (of (Array)),
  mapRej (props (['response', 'data', 'error'])),
  fork (error) (ap ([write (title), write (title_)]))
])
</script>

20 行

let onClick = pipe ([
  getBook (1),
  map (props (['data', 'title'])),
  map (of (Array)),
  mapRej (props (['response', 'data', 'error'])),
  fork (error) (ap ([write (title), write (title_)]))
])

使用 pipe 組合 onClick

  • getBook (1):將 id 傳入 getBook 回傳 Future
  • map (props (['data', 'title'])):在 Resolved 內取得 data.title
  • map (of (Array)):由於要配合 ap 平行寫入 state,因此需將 value 包在 Array 內
  • mapRej (props (['response', 'data', 'error'])):在 Rejected 內取得 response.date.error
  • fork (error) (ap ([write (title), write (title_)])):從 Future 內處理 Rejected 與 Resolved,將多個 write 包在 Array 傳入 ap 平行寫入 state

Conclusion

  • 使用 ap 平行寫入 state,必須將 value 與 function 都包在 Array

Reference

Sanctuary, ap