経緯
reactとfirebaseのrealtime database使って遊んでたら、reduxいらねーな、って気分になってきた。
これmeteorでも感じたやつだ。
こんな気分で書ける
ライブラリでよくみるwithのやーつ。
connect的な名前の方がいいかな。
const HogeContainer = withUserData(({ user, userData }) => (
<div>
{/* 何か */}
</div>
))
何が幸せ?
functional component
で書きたい。
class って書きたくない病。
どうやるのか
authの変更とdatabaseの変更をlistenしてstateに落とすだけのクラスを作ってHOCで返す。
const withUser = (WrappedComponent) => {
return class UserObserver extends Component {
state = {
user: 'not_feached',
owner: 'not_feached',
}
removeAuthListener = null
removeOwnerListener = null
componentDidMount() {
this.removeAuthListener = firebase.auth().onAuthStateChanged(user => {
this.setState({ ...this.state, user })
if (!user) return
this.removeOwnerListener = firebase.database().ref(`users/${user.uid}`).on('value', (snapshot) => {
this.setState({ ...this.state, userData: snapshot.val() })
})
})
}
componentWillUnmount () {
this.removeAuthListener && this.removeAuthListener()
this.removeOwnerListener && this.removeOwnerListener()
}
render() {
const { user, owner } = this.state
return <WrappedComponent {...this.props} {...{ user, owner }} />
}
}
}
export default withUser
実際は、
Userはほとんどの画面で使うだろうから、RouterよりRoot側で観測させれば、別にHOCである必要もないのだけど、
他のnodeの変更を監視するのに使うと、使いたいときに withHoge
を挟むだけで値が手に入るから楽ちん。