Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Контекст в React, Николай Надоричев, MoscowJS 31

601 views

Published on

Контекст стал документированной фичей сравнительно недавно, но его использование либо осуждается, либо не понимается. Такие библиотеки как react-redux или react-router успешно используют для своих нужд. В докладе рассмотрим основные аспекты работы с контекстом: зачем он нужен и какие проблемы решает.

Published in: Internet
  • Be the first to comment

  • Be the first to like this

Контекст в React, Николай Надоричев, MoscowJS 31

  1. 1. Контекст в React Николай Надоричев Frontend-разработчик Сбербанк Технологии 31
  2. 2. • Проблемы коммуникации компонентов • Строим своё дерево компонентов • Пишим свой flux
  3. 3. Коммуникация компонентов • От родителя в ребенку Parent Child Props
  4. 4. Коммуникация компонентов • От ребенка к родителю Parent Child Callbacks
  5. 5. Child Child Child Коммуникация компонентов • От родителя к детям в глубине DOM- дерева Parent Child ???
  6. 6. RadioButtonGroup
  7. 7. RadioButtonGroup <RadioGroup onChange={(value) => alert(value)}>
 <RadioButton value="1">Опция 1</ RadioButton>
 <RadioButton value="2">Опция 2</ RadioButton>
 <RadioButton value="3">Опция 3</ RadioButton>
 </RadioGroup>
  8. 8. RadioButtonGroup class RadioButtonGroup extends React.Component {
 . . .
 childClick() { … }
 
 render() {
 return <div>
 {this.props.children.map((Radio, index) => {
 return React.cloneElement(Radio, {
 onChange: () => this.childClick(value), 
 selected: this.state.value === Radio.props.value,
 key: index})
 })}
 </div>;
 }
 }
  9. 9. RadioButtonGroup class RadioButtonGroup extends React.Component {
 . . .
 childClick() { … }
 
 render() {
 return <div>
 {this.props.children.map((Radio, index) => {
 return React.cloneElement(Radio, {
 onChange: () => this.childClick(value), 
 selected: this.state.value === Radio.props.value,
 key: index})
 })}
 </div>;
 }

  10. 10. RadioButtonGroup class RadioButtonGroup extends React.Component {
 . . .
 childClick() { … }
 
 render() {
 return <div>
 {this.props.children.map((Radio, index) => {
 return React.cloneElement(Radio, {
 onChange: () => this.childClick(value), 
 selected: this.state.value === Radio.props.value,
 key: index})
 })}
 </div>;
 }
 }
  11. 11. RadioButtonGroup <RadioGroup onChange={(value) => alert(value)}>
 <h1>Выберите опцию</h1>
 <div><RadioButton value="1">Опция 1</ RadioButton></div>
 <div><RadioButton value="2">Опция 2</ RadioButton></div>
 <div><RadioButton value="3">Опция 3</ RadioButton></div>
 </RadioGroup>
  12. 12. Child Child Child Коммуникация компонентов • От родителя к детям в глубине DOM- дерева Parent Child Contex t
  13. 13. Context • Передает через специальный аргумент параметры всем дочерним элементам • Пробрасывается, если дочерний элемент запросил параметр явно
  14. 14. RadioButtonGroup class RadioButtonGroup extends React.Component {
 getChildContext() {
 return {
 onRadioChange: () => this.childClick(value),
 radioValue: this.state.value
 }
 }
 } RadioButtonGroup.childContextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 }
  15. 15. RadioButtonGroup class RadioButtonGroup extends React.Component {
 getChildContext() {
 return {
 onRadioChange: () => this.childClick(value),
 radioValue: this.state.value
 }
 }
 } RadioButtonGroup.childContextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 }
  16. 16. RadioButton class RadioButton extends React.Component {
 render() {
 return <div
 className={this.context.selected ? 'radio-active' : 'radio- inactive'}
 onClick={() => this.context.onRadioChange(this.props.value)}>
 {this.props.children}
 </div>;
 }
 }
 
 RadioButton.contextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 };
  17. 17. RadioButton class RadioButton extends React.Component {
 render() {
 return <div
 className={this.context.selected ? 'radio-active' : 'radio- inactive'}
 onClick={() => this.context.onRadioChange(this.props.value)}>
 {this.props.children}
 </div>;
 }
 }
 
 RadioButton.contextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 };
  18. 18. RadioButton class RadioButton extends React.Component {
 render() {
 return <div
 className={this.context.selected ? 'radio-active' : 'radio- inactive'}
 onClick={() => this.context.onRadioChange(this.props.value)}>
 {this.props.children}
 </div>;
 }
 }
 
 RadioButton.contextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 };
  19. 19. RadioButton class RadioButton extends React.Component {
 render() {
 return <div
 className={this.context.selected ? 'radio-active' : 'radio- inactive'}
 onClick={() => this.context.onRadioChange(this.props.value)}>
 {this.props.children}
 </div>;
 }
 }
 
 RadioButton.contextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 };
  20. 20. Component.contextTypes = {
 property: React.PropTypes.any
 };
 
 Component.childContextTypes = {
 property: React.PropTypes.any
 };
  21. 21. Дерево оберток class Leaf extends React.Component {
 childLeaves = [];
 
 getChildContext() {
 return {
 mountLeaf: (instance) => this.childLeaves.push(instance)
 }
 };
 
 componentDidMount() {
 this.context.mountLeaf(this);
 }
 }
 
 Leaf.contextTypes = {
 mountLeaf: React.PropTypes.func
 };
 
 Leaf.childContextTypes = {
 mountLeaf: React.PropTypes.func
 };
  22. 22. Дерево оберток Wrapper Wrapper Wrapper Wrapper Wrapper Wrapper
  23. 23. Дерево оберток
  24. 24. Дерево оберток
  25. 25. Давайте напишем свой flux
  26. 26. WAT?!
  27. 27. Flux через context
  28. 28. FluxContainer constructor() {
 super(...arguments);
 
 this.state = {
 store: this.props.initialStore
 }
 }
  29. 29. FluxContainer dispatchAction(action, params) {
 let store = this.state.store;
 this.props.actions[action](store, params);
 this.setState({store});
 }
  30. 30. FluxWrapper return React.cloneElement(
 React.Children.only(this.props.children),
 {
 dispatch: (action, params) => this.context.dispatchAction(action, params),
 store
 }
 );
  31. 31. App Flux через context FluxContainte r FluxWrapper Component initialStore actions dispatch store dispatch store
  32. 32. Flux через context http://bit.ly/MJS31-flux
  33. 33. Context в СберТехе • AppContainer • SpringWebFlowRouter • Focusable
  34. 34. Спасибо! Вопросы? Надоричев Николай Сбербанк Технологии @luanre @luanre email: luanre@gmail.com http://bit.ly/MJS31-flux Demo flux:
  35. 35. RadioButtonGroup class RadioButtonGroup extends React.Component {
 . . .
 childClick() { … }
 
 render() {
 return <div>
 {this.props.children.map((Radio, index) => {
 return React.cloneElement(Radio, {
 onChange: () => this.childClick(value), 
 selected: this.state.value === Radio.props.value,
 key: index})
 })}
 </div>;
 }
 }
  36. 36. RadioButtonGroup class RadioButtonGroup extends React.Component {
 getChildContext() {
 return {
 onRadioChange: () => this.childClick(value),
 radioValue: this.state.value
 }
 }
 } RadioButtonGroup.childContextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 }
  37. 37. RadioButton class RadioButton extends React.Component {
 render() {
 return <div
 className={this.context.selected ? 'radio-active' : 'radio- inactive'}
 onClick={() => this.context.onRadioChange(this.props.value)}>
 {this.props.children}
 </div>;
 }
 }
 
 RadioButton.contextTypes = {
 onRadioChange: React.PropTypes.func,
 radioValue: React.PropTypes.string
 };

×