React Function Component で副作用(状態、ライフサイクル)を表現する
React Hooks での状態管理と副作用の表現 - mizchi's blog
https://github.com/palmerhq/the-platform
mweststrate/use-immer: Use immer to drive state with a React hooks
yesmeck/react-with-hooks: Ponyfill for the proposed React Hooks API
Mark Dalgleish @ ReactiveConf 🇨🇿 on Twitter: "Hooks, coming soon to a framework near you.… "
acdlite/recompose: A React utility belt for function components and higher-order components.
I will be discontinuing active maintenance of this package (excluding perhaps bugfixes or patches for compatibility with future React releases), and recommending that people use Hooks instead.
Provide React Hooks · Issue #1063 · reduxjs/react-redux
どう対応するか議論中
redux には影響なく、react-redux がどう表現するか、という話になっている。元々 Context API の変更の対応が必要になっており、議論は必要。
Dan 先生曰く、中身は Suspense と一緒なので、Suspense の非同期APIをどう実装されているかで解説する
こんなコードを考える。
const Foo = () => {
const data = readData();
return <pre>{JSON.stringify(data)}</pre>
};
const el = (
<React.Suspense fallback="loading...">
<Foo />
</React.Suspense>
);
コードの見た目上は同期だが、実際には非同期に描画される。
この fetchData
は何をしているか、こう表現することもできる
let data = null
const Foo = () => {
if (data == null) {
throw new Promise(async resolve => {
data = await fetch('/my-data').then(res => res.json());
resolve();
})
}
return <pre>{JSON.stringify(data)}</pre>
}
この throw された Promise は Error Boundary でハンドルされる
class MySuspense extends React.Component {
state = { hasError: false, data: null }
async componentDidCatch(error) {
this.setState({ hasError: true })
const data = await error;
this.setState({ hasError: false, data})
}
render() {
if (this.state.hasError) {
return "Loading...";
} else {
return <Foo {...this.state.data} />
}
}
}
- Foo を render しようとする
- 未初期化なので例外が発生し、promise が throw される
- ErrorBoundary の
componentDidCatch(error)
で 子の render スコープの例外がキャッチされる - ErrorBoundary が promise を解決すると、再び Foo の render が行われる
- Foo の描画が成功
正確には Suspense には描画を間引く機能もある。(TimeSlicing)
このような挙動を本質的には Algebraic Effects というらしく、「継続を取ってこれる例外」とのこと。
React のドメイン知識として、 throw new Promise(...)
は Algebraic Effects の為のイディオムと知っておくといいかもしれない。
追記: Algebraic Effectsとは? 出身は? 使い方は? その特徴とは? 調べてみました! - Qiita
- コアチームが renderProp 推しなので、HOCが推奨されなくなりそう。(recompose の acdlite 氏は Suspense 実装者の一人)
- React.Component のクラス API はあんまり使ってほしくなさそう。すべてが Function Component へ
- Redux は Component の外にあるデータの集約を行う層なので、これによって Redux がなくなるわけではない。ただし connect => mapStateToProps の HOC 的な表現でなくなる可能性は高い
個人的に、 class API は間違ったOOPユーザーへの割れ窓になりがち + 元々 HOC は型推論が難しいという問題があったので、この流れには賛成。
@koichik oops