Slide 1

Slide 1 text

Hooks で作る React.FC @ Takepepe / UIT#6 進化する React.js

Slide 2

Slide 2 text

@Takepepe 吉井 健文 DeNA デザイン本部 デザインエンジニアリングG

Slide 3

Slide 3 text

■ サービスフロントエンド・アニメーション ■ React Hooks と Animation

Slide 4

Slide 4 text

サービスフロントエンド・アニメーション

Slide 5

Slide 5 text

アニメーション「ネガティブ要因」 ■ 冗長な画面遷移 ■ 機能と連動していない動き(ただ派手でカッコ良い) ■ ブラウザ本来とは違う動き(予測不能なインターフェイス) ■ テストが辛い、アニメーションの為にテストコードが冗長に

Slide 6

Slide 6 text

アニメーション と UX ブラウザ閲覧が主戦場となるフロントエンドでは、 いかに表示速度を向上するかが課題。 メディア媒体など、表示速度が定量指標となる場合 「速度 === UX」と言っても過言ではない。

Slide 7

Slide 7 text

アニメーション と UX GUI アプリケーション としての特性が強い場合、 「速度 === UX」と一辺倒に言い切れない。 アプリケーション特性を理解したうえで、 アニメーションを考察する必要がある。

Slide 8

Slide 8 text

アプリケーション特性とアニメーション

Slide 9

Slide 9 text

アニメーションを控えるべき・アプリケーション ■ 表示速度が重要なメディア媒体(Read 要件) ■ 遷移が頻繁なアプリケーション(Read 要件) ■ 素早い入力応答が重要なアプリケーション(Write 要件)

Slide 10

Slide 10 text

アニメーションを控えるべき・アプリケーション 「情報伝達、情報編集」がコアバリューであるものは アニメーションを控えるべき。 求めていないアニメーションは返って悪目立ちし、 不快で使い辛いと感じる。

Slide 11

Slide 11 text

アニメーションを推進するべき・アプリケーション ■ ゲーミフィケーションを含むもの(Play 要件) ■ インセンティブを含むもの(Play 要件) ■ 概要認知が困難なもの(Help 要件) ■ 構成要素が複雑なもの(UI 要件)

Slide 12

Slide 12 text

アニメーションを推進するべき・アプリケーション 明確なユーザーストーリーが描かれているものは アニメーションを活用するべき。 機能としてアニメーション設計をすることで、 コンバージョン達成戦略とすることが出来る。

Slide 13

Slide 13 text

「機能としてのアニメーション設計」5つの言語化

Slide 14

Slide 14 text

1. 通知機能 ■ 提供者の主張に起因するもの ■ 認知が目的であるため、悪目立ちをさせない ■ 余程重要でない場合、UI 操作を奪わない 利用者が提供者に「興味がない」フェーズ

Slide 15

Slide 15 text

2. 補佐機能 ■ アプリケーション開始時のチュートリアルなど ■ UI を理解するための、提供者からの説明 ■ UI 操作を奪った方が、理解に繋がり易い 利用者が提供者に「興味がある」フェーズ

Slide 16

Slide 16 text

3. 認知機能 ■ 現在位置を認知させるためのトランジション ■ どの様な遷移が発生したのかを「数百ms」で視覚伝達する ■ 動きが「情報構造の認知」を促す効果がある 利用者が提供者を「理解する」フェーズ

Slide 17

Slide 17 text

4. 対話機能 ■ ユーザー操作に従順な反応を、快適に感じる ■ ユーザー操作と異なる反応を、不快に感じる ■ リアル・コミュニケーションと同じ。話の腰を折らない 利用者が提供者と「対話する」フェーズ

Slide 18

Slide 18 text

5. 対価機能 ■ アプリケーションからの要求対価(複数・必須項目入力など) ■ 一連の行動対価として演出で応答 ■ 応答の好感度が「RRに直結する」可能性がある 利用者が提供者を「評価する」フェーズ

Slide 19

Slide 19 text

アニメーションはコンバージョン達成の鍵 明確なユーザーストーリーがある場合、 終点の「対価」がコンバージョンと一致する。 利用者にコアバリューを届けるまで、 アニメーションは要所要所で重要な構成要素となり得る。 通知 > 補佐 > 認知 > 対話 > 対価 CV

Slide 20

Slide 20 text

フロントエンドの裁量で決まるアニメーション。 アプリケーション価値を最大化させる 余地が眠っているかも?

Slide 21

Slide 21 text

React Hooks と Animation

Slide 22

Slide 22 text

従来の React x Animation の課題

Slide 23

Slide 23 text

従来の React x Animation の課題 ■ アニメーションが、非同期処理そのもの ■ 関数型指向による Class Component の肩身の狭さ ■ Class Component に変換する手間 ■ CSS に関する知識が必要(CSS書きたくない派閥)

Slide 24

Slide 24 text

従来の React x Animation の課題 アニメーションのためだけに、 Class Component への変換は大儀。 手軽さは無く、優先順位としては低いものだった。 機能要件・非機能要件・テスト >>> アニメーション

Slide 25

Slide 25 text

React Hooks の登場

Slide 26

Slide 26 text

React Hooks で Class Component が不要に ■ DOM の矩形が Function Component でも取得可能になった ■ Function Component でも状態が持てる様になった ■ Life cycle hook と同等の事が可能になった ■ メモ化が随所で簡単になった

Slide 27

Slide 27 text

React Hooks が状態管理に及ぼす影響は? ■ Redux の責務の一部が見直される様になった ■ Redux を代替するものではない ■ Statefull Component ( Class Component ) の状態管理を代替する

Slide 28

Slide 28 text

Statefull Component といえばアニメーション。 アニメーション・コンポーネント作り放題!

Slide 29

Slide 29 text

たくさん作ってみた

Slide 30

Slide 30 text

React Hooks 大喜利 昨年末 React Hooks 発表直後、 「React Hooks で作る GUI」と称し、 アドベントカレンダーとして 24作例 を github に公開 https://github.com/takefumi-yoshii/react-hooks-ogiri

Slide 31

Slide 31 text

React Hooks 大喜利 実装 TIPS も Qiita に24記事。 ■ Cusotom Hooks に責務分割する ■ Presentational 層 と Hooks 層 は別居する ■ Memoize をさぼらない あたりがポイント https://qiita.com/Takepepe/items/8bf3a1a519cb293d220b

Slide 32

Slide 32 text

Animation 処理だけ Custom Hooks に切り出し const ref = useRef(null) const { handleMouseDown, handleMouseUp } = useRippleEffect({ ref, effectDuration: props.effectDuration })

Slide 33

Slide 33 text

const ref = useRef(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

Slide 34

Slide 34 text

従来の Presentational Component の 上位レイヤーとして ※ DOM 構造概念図であり実コードではありません

Slide 35

Slide 35 text

const PieChartContext = createContext( {} as ReturnType ) const Provider: React.FC = props => { const ref = useRef(null) const value = usePieChart({ ref, padding: 0.05, centerCircleRadius: 0.3 }) return (
{props.children}
) } Custom Hooks を Provider に Embed

Slide 36

Slide 36 text

export default () => { const { rectSize, centerCircleRadius } = useContext(PieChartContext) return useMemo( () => ( ), [rectSize, centerCircleRadius] ) } useContext による子の Orchestration

Slide 37

Slide 37 text

Hooks で 0 〜 1 の Animation 係数を更新 useContext で係数を利用し、 各々のユースケースを算出。 style などに適用 ※ DOM 構造概念図であり実コードではありません Animation 進捗に応じた変化

Slide 38

Slide 38 text

const ref = useRef(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 に切り出し

Slide 39

Slide 39 text

const ref = useRef(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 に集約

Slide 40

Slide 40 text

複数の Cusom Hooks を集約。 状態・更新ハンドラーの分配 ※ DOM 構造概念図であり実コードではありません 複数の Custom Hooks を集約・分配 useSomething useSomething useSomething

Slide 41

Slide 41 text

Hooks を利用しなくても作れる(え)

Slide 42

Slide 42 text

React.FC のアイデンティティ

Slide 43

Slide 43 text

React.FC のアイデンティティ これらの実装は、あえて Hooks である必要はない。 従来の Statefull Component と 非同期 middleWare でも スタックとしては問題なく実現出来る。

Slide 44

Slide 44 text

React.FC のアイデンティティ Hooks があるからといって Class Component が 廃止されるものではない、と明言されている。 現在、Dependencies に Class Component を利用した ライブラリが含まれていても憂慮する必要はない。 (ただしこれからは Class Component を書く必要はない)

Slide 45

Slide 45 text

React.FC のアイデンティティ 既存の Function Component に対し、 アニメーションを「ちょい足し」できる。 Redux を中心に量産した Function Component に、 息を吹き込むことが出来る。

Slide 46

Slide 46 text

まとめ

Slide 47

Slide 47 text

■ React Hooks で容易に実装ができる ■ アプリケーションとの対話であることを意識 ■ アプリケーション特性に基づいた設計を アニメーションのこれから

Slide 48

Slide 48 text

フロントエンドエンジニアは ユーザーにサービスを届ける最後の砦です。 自分たちにしかリーチ出来ない領域で アプリケーション価値を最大化させましょう!

Slide 49

Slide 49 text

ご静聴ありがとうございました