點燈坊

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

使用 writeStorage() 寫入 Local Storage

Sam Xiao's Avatar 2020-08-25

Local Storage 雖可透過 Web API 的 localStorage.setItem() 寫入,但其並非 Curried Function 不適合 Function Pipeline,Wink-fp 特別包成適合 FP 的 writeStorage()

Version

macOS Catalina 10.15.6
Wink-fp 1.20.99

Functional

write000

按下 Write Local Storage 會寫入 local storage。

<template>
  <div>
    <button @click="onWrite">Write Local Storage</button>
  </div>
</template>

<script>
import { pipe, curry, bind, always } from 'ramda'

let writeStorage = pipe(
  always(localStorage),
  bind(localStorage.setItem),
  curry
)()

let onWrite = function() {
  writeStorage('name')(this.name)
}

export default {
  name: 'App',
  data: () => ({
    name: 'Sam'
  }),
  methods: {
    onWrite,
  }
}
</script>

10 行

let writeStorage = pipe(
  always(localStorage),
  bind(localStorage.setItem),
  curry
)()

若使用 Web API,寫入 local storage 要使用 localStorage.setItem(),但這種 API 並非 curried function 不適合 Function Pipeline。

  • 使用 always() K combinator 回傳 localStorage
  • 使用 bind()localStorae.setItem() 取出 free function
  • 使用 curry() 將 normal function 轉成 curried function

15 行

let onWrite = function() {
  writeStorage('name')(this.name)
}

writeStorage() 為 curried function。

Wink-fp

<template>
  <div>
    <button @click="onWrite">Write Local Storage</button>
  </div>
</template>

<script>
import { writeStorage } from 'wink-fp'

let onWrite = function() {
  writeStorage('name')(this.name)
}

export default {
  name: 'App',
  data: () => ({
    name: 'Sam'
  }),
  methods: {
    onWrite,
  }
}
</script>

第 8 行

import { writeStorage } from 'wink-fp'

let onWrite = function() {
  writeStorage('name')(this.name)
}

writeStorage() 實務上經常使用,Wink-fp 已經內建。

writeStorage()
String -> a -> void
localStorae.setItem() 的 curried function 版本

String:寫入 local storage 的 key

a:寫入 local storage 的 value

void:沒有回傳值

Vue 3

<template>
  <button @click="onWrite">Write Local Storage</button>
</template>

<script>
import { ref } from 'vue'
import { pipe, always } from 'ramda'
import { unwrap } from 'vue3-fp'
import { writeStorage } from 'wink-fp'

let name = ref('Sam')

let onWrite = pipe(
  unwrap(name),
  writeStorage('name')
)

let setup = pipe(
  always({ name, onWrite })
)

export default {
  name:'App',
  setup
}
</script>

13 行

let onWrite = pipe(
  unwrap(name),
  writeStorage('name')
)

writeStorage() 要在 Vue 3 才能發揮威力。

由於 writeStorage() 為 curried function,因此可輕易整合進 Function Pipeline 中:

  • 使用 unwrap() 讀取 name reactive model
  • 使用 writeStorage() 寫入 local storage

若使用 Web API 的 localStorae.setItem(),則根本無法透過 Function Pipeline 組合出 onWrite()

Conclusion

  • Web API 當初是以 OOP 設計,因此與 FP 格格不入,可自己將 Web API 包成 curried function 方便 Function Pipeline
  • Curried function 在 Vue 2 看不出威力,但在 Vue 3 因為有了 Composition API,能輕易在 Function Pipeline 內使用 curried function

Reference

Reference

MDN, Storage.setItem()