22行だけでReactのHooksを実装する!
React 16.8で使えるようになったHooks APIは、人によって魔法にしか見えない。しかし、Hooksの背景にあるアイデアは本当はとても簡単!この短い投稿を読み終わった頃には、Hooksは本質的に何なのかを理解できるはず。
注意: この投稿を読む人には、Javascriptと多少のReactの知識があるという前提で作っています
ということで、この投稿(英語)を参考にしながら、useEffect
とuseState
をゼロから実装してみよう。
useState
とuseEffect
const MyReact = (function() {
let hooks = [] // Hooksの配列
let currentHook = 0 // イテレータ
return {
useEffect(callback, depArray) {
// depArrayは、エフェクトを実行すべきかどうか判断するために与えられる値の配列
const hasNoDeps = !depArray // depArrayがundefinedの場合True, それ以外False
const deps = hooks[currentHook] // Array | undefined
// depsがundefinedじゃない場合、前回レンダーと比べて配列の中の値が変わったかをチェック
const hasChangedDeps = deps ? !depArray.every((el, i) => el === deps[i]) : true
if (hasNoDeps || hasChangedDeps) {
// depsの配列がない場合とdepsが変わった場合は、毎回レンダー時にエフェクトを実行
callback()
hooks[currentHook] = depArray // 最新のdepArrayを覚える
}
currentHook++ // 次のHookに進む
},
useState(initialValue) {
hooks[currentHook] = hooks[currentHook] || initialValue
const setStateHookIndex = currentHook
// currentHookをそのまま使うと、クロージャのせいでsetStateが実行されたとき、
// インデックスがコンポーネントのレンダー順番と一致することを保証できないので、
// 変わらない値にインデックスを保存する
const setState = newState => (hooks[setStateHookIndex] = newState)
return [hooks[currentHook++], setState] // 値と関数を戻し、次のHookに進む
}
}
})()
以上!コメントを除けば、この22行だけで、Hooksが実装できた!
公式のHooksのコードを見てみると、一見だいぶ違うように見えるが、それはReactのFiber設計の独特な実装がかかわっているからで、関数の定義をよく調べれば、上記の実装にかなり近いことがわかる。
一番注目すべきところは、イテレータの存在。
Hooksを使うときは、それぞれのuseState
は、なぜ正しいコンポーネントのステートがわかるのか?という疑問を持ったことがあるだろう。実は、Reactがレンダーの順番にHookの保存を合わせているだけだった。ひとつのHooksのルールとしては、「条件やループの中でuseState
やuseEffect
を呼ばない」があるのは、そのためだ。開発者が作る条件は、Reactの範囲外なので、正しい値を返すことを保証できない。
補足
厳密にいえば、HooksはReactとはまったく関係がない。上記のコードを見てみると、React特有のコードが一行もなく、やろうと思えば、別のライブラリ、別の目的で活かせることがわかる。実は、React以外のところで使うためのHookライブラリを、@getifyが作っている。Githubリンク:https://github.com/getify/TNG-Hooks
Author And Source
この問題について(22行だけでReactのHooksを実装する!), 我々は、より多くの情報をここで見つけました https://qiita.com/jlkiri/items/f79210908b3204c7fd9f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .