Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hooks で作る React.FC<Animation>

Takepepe
March 20, 2019

Hooks で作る React.FC<Animation>

Takepepe

March 20, 2019
Tweet

More Decks by Takepepe

Other Decks in Technology

Transcript

  1. 従来の React x Animation の課題 ▪ アニメーションが、非同期処理そのもの ▪ 関数型指向による Class

    Component の肩身の狭さ ▪ Class Component に変換する手間 ▪ CSS に関する知識が必要(CSS書きたくない派閥)
  2. React Hooks で Class Component が不要に ▪ DOM の矩形が Function

    Component でも取得可能になった ▪ Function Component でも状態が持てる様になった ▪ Life cycle hook と同等の事が可能になった ▪ メモ化が随所で簡単になった
  3. React Hooks 大喜利 昨年末 React Hooks 発表直後、 「React Hooks で作る

    GUI」と称し、 アドベントカレンダーとして 24作例 を github に公開 https://github.com/takefumi-yoshii/react-hooks-ogiri
  4. React Hooks 大喜利 実装 TIPS も Qiita に24記事。 ▪ Cusotom

    Hooks に責務分割する ▪ Presentational 層 と Hooks 層 は別居する ▪ Memoize をさぼらない あたりがポイント https://qiita.com/Takepepe/items/8bf3a1a519cb293d220b
  5. Animation 処理だけ Custom Hooks に切り出し const ref = useRef<HTMLButtonElement |

    null>(null) const { handleMouseDown, handleMouseUp } = useRippleEffect({ ref, effectDuration: props.effectDuration })
  6. const ref = useRef<HTMLDivElement | null>(null) const { itemWidth, itemHeight,

    nodeStyle, containerStyle } = usePhotoCarousel({ ref, imagesCount: props.images.length, imageRatio: props.imageRatio, transitionInterval: props.transitionInterval, transitionDuration: props.transitionDuration, onChangeCurrent: props.onChangeCurrent }) jQuery Plugin を彷彿とさせる optional injection
  7. <Container> <Presentational /> </Container> <Container> <CustomHooks> <Presentational /> </CustomHooks> </Container>

    従来の Presentational Component の 上位レイヤーとして ※ DOM 構造概念図であり実コードではありません
  8. const PieChartContext = createContext( {} as ReturnType<typeof usePieChart> ) const

    Provider: React.FC = props => { const ref = useRef<HTMLDivElement | null>(null) const value = usePieChart({ ref, padding: 0.05, centerCircleRadius: 0.3 }) return ( <PieChartContext.Provider value={value}> <div ref={ref}>{props.children}</div> </PieChartContext.Provider> ) } Custom Hooks を Provider に Embed
  9. export default () => { const { rectSize, centerCircleRadius }

    = useContext(PieChartContext) return useMemo( () => ( <View rectSize={rectSize} centerCircleRadius={centerCircleRadius} center={rectSize * 0.5} /> ), [rectSize, centerCircleRadius] ) } useContext による子の Orchestration
  10. Hooks で 0 〜 1 の Animation 係数を更新 <Provider customHooks={customHooks}>

    <SVG> <Hooks useContext={providerContext}> <Element /> <Element /> </Hooks> <Hooks useContext={providerContext}> <Element /> </Hooks> <Element /> </SVG> <Hooks useContext={providerContext}> <Presentational /> </Hooks> </Provider> useContext で係数を利用し、 各々のユースケースを算出。 style などに適用 ※ DOM 構造概念図であり実コードではありません Animation 進捗に応じた変化
  11. const ref = useRef<HTMLDivElement | null>(null) const [rect, setRect] =

    useState({ width: 0, height: 0 }) useEffect(() => { const handleResize = () => { if (ref.current === null) return const { width, height } = ref.current.getBoundingClientRect() setRect({ width, height }) } handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) DOM 矩形取得だけ Custom Hooks に切り出し
  12. const ref = useRef<HTMLDivElement | null>(null) const [rect, setRect] =

    useState({ width: 0, height: 0 }) useEffect(() => { const handleResize = () => { if (ref.current === null) return const { width, height } = ref.current.getBoundingClientRect() setRect({ width, height }) } handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) 分割 した Custom Hooks を 1つの Custom Hooks に集約
  13. 複数の Cusom Hooks を集約。 状態・更新ハンドラーの分配 <Provider customHooks={customHooks}> <SVG> <Hooks useContext={providerContext}>

    <Element /> <Element /> </Hooks> <Hooks useContext={providerContext}> <Element /> </Hooks> <Element /> </SVG> <Hooks useContext={providerContext}> <Presentational /> </Hooks> </Provider> ※ DOM 構造概念図であり実コードではありません 複数の Custom Hooks を集約・分配 useSomething useSomething useSomething
  14. React.FC<Animation> のアイデンティティ Hooks があるからといって Class Component が 廃止されるものではない、と明言されている。 現在、Dependencies に

    Class Component を利用した ライブラリが含まれていても憂慮する必要はない。 (ただしこれからは Class Component を書く必要はない)