概要

Reactでのcontextについて

props? context?

propsの短所

  • React.jsのコンポーネント間で情報を渡すためには props を使うわけですが
  • しかし明示的に指定しないと行けない
  • child componentのdepthが深い場合には不向き
    • componentの結合度が高くなる

なので、contextをつかう

context

  • material-ui (mui)でもよくつかわれる

childContextTypes/getChildContext によって作られた Context は App モジュールの子孫にわたって引き継がれていくようで、 muiの各コンポーネントはこの Context から muiTheme を得て、そ の見た目を決めていると思われます。

https://facebook.github.io/react/docs/context.htmlから

  • Occasionally, you want to pass data through the component tree without having to pass the props down manually at every level. React's "context" feature lets you do this.

  • When not to use context

    • The best use cases for context are for implicitly passing down the logged-in user, the current language, or theme information
    • Do not use context to pass your data thorough components. !!!

利用方法

  • parentでchildContextTypes定義
  • childでcontextTypesを定義
  • this.contextで利用

override

もし、grandparentとparentがいて、parentで、同じcontextを上書きしたらchildは上書きされてデータをもらう

https://jsbin.com/fuxodipuho/edit?js,output

sample

from https://github.com/moreta/study-reactjs/tree/master/frontend-boilerplate/client/containers/ContextTest

Parent

// http://y-ukatama.hateblo.jp/entry/2015/07/08/132847
// を書き換え
import React, {Component, PropTypes} from 'react'
import Content from './content'
import Child from './child'

export default class Parent extends Component {

  constructor(props) {
    super(props)
    this.state = { text: null }
  }


  getChildContext() {
    return {
      title: 'title1',
      text: this.state.text
    }
  }

  componentDidMount() {
    setTimeout(function() {
      console.log('call setState')
      this.setState({ text: 'some text' })
    }.bind(this), 1500)
  }

  tick = () => {
    console.log('call tick')
    this.setState({ text: 'some text2' })
  };


  render() {
    return (
      <Child>
        <Content onClick={this.tick} />
      </Child>
    )
  }
}

Parent.childContextTypes = {
  title: PropTypes.string,
  text: PropTypes.string
}

Child

// http://y-ukatama.hateblo.jp/entry/2015/07/08/132847
// を書き換え
import React, {Component, PropTypes} from 'react'
import Content from './content'

export default class Child extends Component {

  render() {
    return (
      <div>{this.props.children}</div>
    )
  }
}

Child.childContextTypes = {
  title: PropTypes.string,
  text: PropTypes.string
}

Content

import React, {Component, PropTypes} from 'react'

export default class Content extends Component {

  render() {
    return (
      <div onClick={this.props.onClick}>
        {this.context.title + ': ' + (this.context.text || 'no text')}
      </div>
    )
  }
}

Content.contextTypes = {
  title: PropTypes.string,
  text: PropTypes.string
}

What should be in the context

React libraries

  • Fluxible adds getStore and executeAction to component context
  • React-router adds an router object to the context for routing
  • react-intl adds messages, formats objects and locales string|array to the context for translations and text formating.

For a library, context is a good way for sharing data/functionalities in react components without polluting the application business logic. libarayでcontextはdataや機能を提供するためのいい方法の一つ(ビジネスロジックを汚染させずに)

ほか、

  • logged-in user
  • current language(react-intlと同じかな)
  • theme

などにも利用していい

その他

parent-based and owner-based context

React has officially said that parent-based context will be the future and owner-based context is deprecated

https://gist.github.com/jimfb/0eb6e61f300a8c1b2ce7

References

results matching ""

    No results matching ""