recompose を使うと見た目の component とロジックを切り離して書けるのでスッキリする、というような記事を先日書いた(Storybook Driven Development を試している)のだが、React の ref の使い方で大いにハマったので書いておく。
アプリケーションを作っていると、往々にして componentDidUpdate などで ref を参照したいということが発生する。普通に class で書いていると
class extends React.Component {
  componentDidUpdate() {
    this.textarea // => <textarea />
  }
  render() {
    return (
      <textarea ref={textarea => (this.textarea = textarea)} />
    }
  }
}
という風に書くが、recompose を使っていると
const enhance = lifecycle({
  componentDidUpdate() {
    // ???
  }
})
enhance(() => (<textarea ref={???} />))
というような形に分離する。この時、先に示したように ref で this に代入しても、componentDidUpdate の中では this は ProxyComponent となっていて ref が読み出せなくなってしまう。これを解決するためには、withHandlers を併用する。
const enhance = compose(
  withHandlers(() => {
    let refs = {}
    return {
      onRef: props => textarea => (refs.textarea = textarea),
      onUpdate: props => refs.textarea // として参照できる!!
    }
  }),
  lifecycle({
    componentDidUpdate() {
      this.props.onUpdate()
    }
  })
)
enhance(props => (<textarea ref={props.onRef} />))
これで recompose でも ref を取り扱うことができた。
 

 
    
Top comments (0)