hyperapp-nestableを使うと、stateとactionsとviewを持ったコンポーネントが作れるわけですが、当然ながら@hyperapp/loggerには対応していません。でも僕はロギングしたい。
@hyperapp/loggerのコードを読む
楽をしたいので既存のloggerのコードが流用できるならしたいので、読んでみます。
コードを読むにmakeLoggerAppという関数にメインの機能が実装されていて、その中にはenhanceActionsというのがあります。この関数の中でactionsにロギングする機能を付与しているみたいなので、これだけ切り出してactionsをenhanceしてからnestableに食わせればnestableで作ったコンポーネントのStateの変遷をロギングできます。
エンハンスやで
ライブラリにするわけではなくプロジェクト内で使う予定なのでちょっとES6っぽく書き直して切り出すとこんな感じかと。
enhanceActions.js
function defaultLog (prevState, action, nextState) {
console.group('%c action', 'color: gray; font-weight: lighter;', action.name)
console.log('%c prev state', 'color: #9E9E9E; font-weight: bold;', prevState)
console.log('%c data', 'color: #03A9F4; font-weight: bold;', action.data)
console.log('%c next state', 'color: #4CAF50; font-weight: bold;', nextState)
console.groupEnd()
}
const enhance = (actionsTemplate) => {
const enhanceActions = (actions, prefix) => {
const namespace = prefix ? prefix + '.' : ''
return Object.keys(actions || {}).reduce((otherActions, name) => {
const namedspacedName = namespace + name
const action = actions[name]
otherActions[name] =
typeof action === 'function'
? (data) => (state, actions) => {
let result = action(data)
result =
typeof result === 'function'
? result(state, actions)
: result
defaultLog(state, { name: namedspacedName, data }, result)
return result
}
: enhanceActions(action, namedspacedName)
return otherActions
}, {})
}
const enhancedActions = enhanceActions(actionsTemplate)
return enhancedActions
}
ロギング機能を付与したactionsをnestableに食わせるとこう。
nestabledComponent.js
import nestable from 'hyperapp-nestable'
const state = { count: 0 }
const actions = { up: () => ({count}) => ({count: count + 1}) }
const view = (state, actions) =>
<div>
<p>{state.count}</p>
<button onclick={actions.up}>up</button>
</div>
nestable(state, enhanceActions(actions), view)
これでロギングできるようになった。こないだ書いたnestableで作ったコンポーネントで無理矢理Lazy Componentsするやつも使えばややこしいがnestableが強くなる。