點燈坊

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

使用 guardEffect 自動重新執行 Side Effect

Sam Xiao's Avatar 2021-08-24

Vue 3 希望我們使用 watchEffect 自動重新執行 Side Effect,但這種方式不方便 Point-free,Vue3-fp 提供了 Curry Function 版本的 guardEffect

Version

Vue 3.2
Vue3-fp 0.3.2

Composition API

effect000

3 為 state,而 4watchEffect 所維護,state 會不斷遞增,而 watchEffect 會永遠比 state 多加 1

<template>
  {{ count }} {{ plus }}
</template>

<script setup>
import { watchEffect } from 'vue'

let count = $ref (0)
let plus = $ref (0)

watchEffect (_ => plus = count + 1)
setInterval (_ => count++, 1000)
</script>

11 行

watchEffect (_ => plus = count + 1)

使用 watchEffect 寫入 plus state,若 count state 改變則會觸發 watchEffect

12 行

setInterval (_ => count++, 1000)

使用 setInterval 每一秒鐘對 count state 遞增。

Point-free

effect000

結果不變,但使用 Point-free 改寫。

<template>
  {{ count }} {{ plus }}
</template>

<script setup>
import { ref, watchEffect } from 'vue'
import { read, write } from 'vue3-fp'
import { pipe, inc, always as K } from 'ramda'
import { interval } from 'wink-fp'

let count = ref (0)
let plus = ref (0)

let guardEffect = (...f) => _ => watchEffect (pipe (...f))

let incCount = pipe (
  read (count),
  inc,
  write (count)
)

guardEffect (
  read (count),
  inc,
  write (plus)
) ()

pipe (
  K (incCount),
  interval (1000),
) ()
</script>

22 行

guardEffect (
  read (count),
  inc,
  write (plus)
) ()

使用 guardEffect 組合出 watchEffect

  • read (count):讀取 count state
  • inc:對值遞增
  • write (plus):寫入 plus state

14 行

let guardEffect = (...f) => _ => watchEffect (pipe (...f))

guardEffect 本質還是 watchEffect,只是方便 Point-free 使用。

Vue3-fp

effect000

結果不變,但使用 Vue3-fp 改寫。

<template>
  {{ count }} {{ plus }}
</template>

<script setup>
import { ref } from 'vue'
import { read, write, guardEffect } from 'vue3-fp'
import { pipe, inc, always as K } from 'ramda'
import { interval } from 'wink-fp'

let count = ref (0)
let plus = ref (0)

let incCount = pipe (
  read (count),
  inc,
  write (count)
)

guardEffect (
  read (count),
  inc,
  write (plus)
) ()

pipe (
  K (incCount),
  interval (1000),
) ()
</script>

第 7 行

import { read, write, guardEffect } from 'vue3-fp'

Vue3-fp 已經內建 guardEffect 可直接使用。

guardEffect :: (...Function) -> void
組合 function 實現 watchEffect

(...Function):可傳入個數不限的 function

void:不回傳任何值

Conclusion

  • watchEffect 不方便 Point-free,使用 guardEffect() 才適合 Point-free