class Product Row extends Component should Component Updatenext

  • Slides: 93
Download presentation

Перерисовка компонентов class Product. Row extends Component { should. Component. Update(next. Props) { return

Перерисовка компонентов class Product. Row extends Component { should. Component. Update(next. Props) { return next. Props. id !== this. props. id } render() { //. . . } } 10

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting =

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting = Wrapped. Component => props => ( <div> Hi, <Wrapped. Component {. . . props} /> </div> ) with. Greeting(Name) 12

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting =

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting = Wrapped. Component => props => ( <div> Hi, <Wrapped. Component {. . . props} /> </div> ) with. Greeting(Name) 13

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting =

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting = Wrapped. Component => props => ( <div> Hi, <Wrapped. Component {. . . props} /> </div> ) with. Greeting(Name) 14

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting =

Компонент высшего порядка (HOC) const Name = () => <p>Guest</p> const with. Greeting = Wrapped. Component => props => ( <div> Hi, <Wrapped. Component {. . . props} /> </div> ) with. Greeting(Name) 15

only. Update. For. Keys const Product. Row = only. Update. For. Keys(['id)([' }) id,

only. Update. For. Keys const Product. Row = only. Update. For. Keys(['id)([' }) id, name, price /*. . . больше свойств) <= ({ /* > tr< > td>{name}</td< > td>{price}</td< > Link to={`/products/${id}`}>Details</Link< /> td< /> tr< ( ( 16

only. Update. For. Keys const enhance = only. Update. For. Keys(['id([' const Product. Row

only. Update. For. Keys const enhance = only. Update. For. Keys(['id([' const Product. Row = ({ id, name, price /*. . . больше свойств) <= ({ /* > tr< > td>{name}</td< > td>{price}</td< > Link to={`/products/${id}`}>Details</Link< /> td< /> tr< ( export default enhance(Product. Row( 17

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped.

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped. Component => class extends Component { should. Component. Update(next. Props) { return prop. Keys. some(key => this. props[key] !== next. Props[key] ) } render() { return <Wrapped. Component {. . . this. props} /> } } 18

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped.

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped. Component => class extends Component { should. Component. Update(next. Props) { return prop. Keys. some(key => this. props[key] !== next. Props[key] ) } render() { return <Wrapped. Component {. . . this. props} /> } } 19

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped.

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped. Component => class extends Component { should. Component. Update(next. Props) { return prop. Keys. some(key => this. props[key] !== next. Props[key] ) } render() { return <Wrapped. Component {. . . this. props} /> } } 20

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped.

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped. Component => class extends Component { should. Component. Update(next. Props) { return prop. Keys. some(key => this. props[key] !== next. Props[key] ) } render() { return <Wrapped. Component {. . . this. props} /> } } 21

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped.

only. Update. For. Keys const only. Update. For. Keys = prop. Keys => Wrapped. Component => class extends Component { should. Component. Update(next. Props) { return prop. Keys. some(key => this. props[key] !== next. Props[key] ) } render() { return <Wrapped. Component {. . . this. props} /> } } 22

Граничные условия в render const Product. List = ({ products) <= ({ > table<

Граничные условия в render const Product. List = ({ products) <= ({ > table< > thead< > tr< > th>Name</th< > th>Price</th< /> tr< /> thead< > tbody< } products. map(p <= >Product. Row key={p. id} {. . . p{(</ { /> tbody< /> table< ( 24

Граничные условия в render const Product. List = ({ products} <= ({ if (!products.

Граничные условия в render const Product. List = ({ products} <= ({ if (!products. length} ( return <No. Data /> { return) > table< */} та же таблица{/* /> table< ( { 25

Граничные условия в render const Product. List = ({ loading, products} <= ({ if

Граничные условия в render const Product. List = ({ loading, products} <= ({ if (loading} ( return <Spinner</ { if (!products. length} ( return <No. Data</ { return (. . . ( { 26

Граничные условия в render const Product. List = ({ current. User, loading, products} <=

Граничные условия в render const Product. List = ({ current. User, loading, products} <= ({ if (!current. User} ( return <Not. Authorized</ { if (loading} ( return <Spinner</ { if (!products. length} ( return <No. Data</ { return (. . . ( { 27

Граничные условия в render const enhance = branch( ({ products }) => !products. length,

Граничные условия в render const enhance = branch( ({ products }) => !products. length, () => null ) const Product. List = ({ products }) => (. . . ) export default enhance(Product. List) 28

Граничные условия в render const enhance = branch( ({ products }) => !products. length,

Граничные условия в render const enhance = branch( ({ products }) => !products. length, () => null ) const Product. List = ({ products }) => (. . . ) export default enhance(Product. List) 29

Граничные условия в render const enhance = branch( ({ products }) => !products. length,

Граничные условия в render const enhance = branch( ({ products }) => !products. length, () => null ) const Product. List = ({ products }) => (. . . ) export default enhance(Product. List) 30

Граничные условия в render const render. Nothing = () => null const enhance =

Граничные условия в render const render. Nothing = () => null const enhance = branch( ({ products }) => !products. length, render. Nothing ) const Product. List = ({ products }) => (. . . ) export default enhance(Product. List) 31

branch const branch = (cond, cb) => Wrapped. Component => props => cond(props) ?

branch const branch = (cond, cb) => Wrapped. Component => props => cond(props) ? cb(props) : <Wrapped. Component {. . . props} /> 32

branch const branch = (cond, cb) => Wrapped. Component => props => cond(props) ?

branch const branch = (cond, cb) => Wrapped. Component => props => cond(props) ? cb(props) : <Wrapped. Component {. . . props} /> 33

Подготовка данных для отрисовки const formatted. Price = price => `$${price}` const enhance =

Подготовка данных для отрисовки const formatted. Price = price => `$${price}` const enhance = only. Update. For. Keys(['id']) const Product. Row = ({ id, name, price }) => ( <tr> <td>{name}</td> <td>{formatted. Price(price)}</td> <Link to={`/products/${id}`}>Details</Link> </td> </tr> ) export default enhance(Product. Row) 35

Подготовка данных для отрисовки const formatted. Price = price => `$${price}` const enhance =

Подготовка данных для отрисовки const formatted. Price = price => `$${price}` const enhance = only. Update. For. Keys(['id'])( with. Props(({ price }) => ({ price: formatted. Price(price) })) ) const Product. Row = ({ id, name, price }) => (. . . ) export default enhance(Product. Row) 36

with. Props const with. Props = mapper => Wrapped. Component => props => {

with. Props const with. Props = mapper => Wrapped. Component => props => { const new. Props = {. . . props, . . . mapper(props) } return <Wrapped. Component {. . . new. Props} /> } 37

with. Props const with. Props = mapper => Wrapped. Component => props => {

with. Props const with. Props = mapper => Wrapped. Component => props => { const new. Props = {. . . props, . . . mapper(props) } return <Wrapped. Component {. . . new. Props} /> } 38

Композиция with. Router( inject. Intl( connect(map. State. To. Props, map. Dispatch. To. Props) )

Композиция with. Router( inject. Intl( connect(map. State. To. Props, map. Dispatch. To. Props) ) )(Landing. Page) 39

Композиция const enhance = compose( with. Router, inject. Intl, connect(map. State. To. Props, map.

Композиция const enhance = compose( with. Router, inject. Intl, connect(map. State. To. Props, map. Dispatch. To. Props) ) enhance(Landing. Page) 40

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc,

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc, hoc) => hoc(acc), Wrapped. Component) 41

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc,

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc, hoc) => hoc(acc), Wrapped. Component) 42

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc,

compose const compose = (. . . hocs) => Wrapped. Component => hocs. reduce((acc, hoc) => hoc(acc), Wrapped. Component) 43

with. Props const formatted. Price = price => `$${price}` const enhance = only. Update.

with. Props const formatted. Price = price => `$${price}` const enhance = only. Update. For. Keys(['id'])( with. Props(({ price }) => ({ price: formatted. Price(price) })) ) const Product. Row = ({ id, name, price }) => (. . . ) export default enhance(Product. Row) 44

with. Props const formatted. Price = price => `$${price}` const enhance = compose( only.

with. Props const formatted. Price = price => `$${price}` const enhance = compose( only. Update. For. Keys(['id']), with. Props(({ price }) => ({ price: formatted. Price(price) })) ) const Product. Row = ({ id, name, price }) => (. . . ) export default enhance(Product. Row) 45

recompose • • https: //github. com/acdlite/recompose 15. 1 k. B minified, 4 k. B

recompose • • https: //github. com/acdlite/recompose 15. 1 k. B minified, 4 k. B gzipped, � 9700 есть все функции, которые мы реализовали и множество других хорошая поддержка �flow �Rx. JS �Type. Script �React Native 46

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add.

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add. To. Cart }) => ( <div> <span>{price}</span> <button on. Click={() => on. Add. To. Cart(product. Id)}> Add to cart </button> </div> ) 48

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add.

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add. To. Cart }) => ( <div> <span>{price}</span> <button on. Click={() => on. Add. To. Cart(product. Id)}> Add to cart </button> </div> ) 49

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add.

with. Handlers const Add. To. Cart. Button = ({ price, product. Id, on. Add. To. Cart }) => ( <div> <span>{price}</span> <button on. Click={() => on. Add. To. Cart(product. Id)}> Add to cart </button> </div> ) 50

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To.

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To. Cart, product. Id }) => () => on. Add. To. Cart(product. Id) }) const Add. To. Cart. Button = ({ price, on. Click. Handler }) => ( <div> <span>{price}</span> <button on. Click={on. Click. Handler}>Add to cart</button> </div> ) export default enhance(Add. To. Cart. Button) 51

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To.

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To. Cart, product. Id }) => () => on. Add. To. Cart(product. Id) }) const Add. To. Cart. Button = ({ price, on. Click. Handler }) => ( <div> <span>{price}</span> <button on. Click={on. Click. Handler}>Add to cart</button> </div> ) export default enhance(Add. To. Cart. Button) 52

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To.

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To. Cart, product. Id }) => () => on. Add. To. Cart(product. Id) }) const Add. To. Cart. Button = ({ price, on. Click. Handler }) => ( <div> <span>{price}</span> <button on. Click={on. Click. Handler}>Add to cart</button> </div> ) export default enhance(Add. To. Cart. Button) 53

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To.

with. Handlers const enhance = with. Handlers({ on. Click. Handler: ({ on. Add. To. Cart, product. Id }) => () => on. Add. To. Cart(product. Id) }) const Add. To. Cart. Button = ({ price, on. Click. Handler }) => ( <div> <span>{price}</span> <button on. Click={on. Click. Handler}>Add to cart</button> </div> ) export default enhance(Add. To. Cart. Button) 54

Загрузка данных class Product. List. Container extends Component { constructor(props) { /* инициализируем cтейт

Загрузка данных class Product. List. Container extends Component { constructor(props) { /* инициализируем cтейт */ } load. Products = () => { /* идем на сервер за данными */ } component. Will. Mount() { this. load. Products() } render() { /* рисуем */ } } 56

Загрузка данных class Product. List. Container extends Component { constructor(props) { super(props) this. state

Загрузка данных class Product. List. Container extends Component { constructor(props) { super(props) this. state = { products: [], loading: false } } //. . . } 57

Загрузка данных class Product. List. Container extends Component { load. Products = () =>

Загрузка данных class Product. List. Container extends Component { load. Products = () => { this. set. State({ loading: true }) fetch. Products(). then(products => this. set. State({ products, loading: false }) ) } //. . . } 58

Загрузка данных class Product. List. Container extends Component { render() { return ( <Product.

Загрузка данных class Product. List. Container extends Component { render() { return ( <Product. List products={this. state. products} loading={this. state. loading} /> ) } //. . . } 59

class Product. List. Container extends Component { constructor(props) { super(props) this. state = {

class Product. List. Container extends Component { constructor(props) { super(props) this. state = { products: [], loading: false } } load. Products = () => { this. set. State({ loading: true }) fetch. Products(). then(products => this. set. State({ products, loading: false }) ) } component. Will. Mount() { this. load. Products() } render() { const { products, loading } = this. state return (<Product. List products={products} loading={loading} />) } } 60

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false),

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false), with. Handlers({ load. Products: ({ set. Loading, set. Products }) => () => { set. Loading(true) fetch. Products(). then(products => { set. Loading(false) set. Products(products) }) } }), lifecycle({ component. Will. Mount() { this. props. load. Products() } }) ) export default enhance(Product. List) 61

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false),

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false), with. Handlers({ load. Products: ({ set. Loading, set. Products }) => () => { set. Loading(true) fetch. Products(). then(products => { set. Loading(false) set. Products(products) }) } }), lifecycle({ component. Will. Mount() { this. props. load. Products() } }) ) export default enhance(Product. List) 62

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false),

const enhance = compose( with. State('products', 'set. Products', []), with. State('loading', 'set. Loading', false), with. Handlers({ load. Products: ({ set. Loading, set. Products }) => () => { set. Loading(true) fetch. Products(). then(products => { set. Loading(false) set. Products(products) }) } }), lifecycle({ component. Will. Mount() { this. props. load. Products() } }) ) export default enhance(Product. List) 63

component. From. Prop <Navbar> <Navbar. Item to={home. Path}>Home</Navbar. Item> <Navbar. Item to={cart. Path}>Cart</Navbar. Item>

component. From. Prop <Navbar> <Navbar. Item to={home. Path}>Home</Navbar. Item> <Navbar. Item to={cart. Path}>Cart</Navbar. Item> <Navbar. Item on. Click={sign. Out}>Sign Out</Navbar. Item> </Navbar> 65

component. From. Prop const Navbar. Item = ({ to, on. Click, children }) =>

component. From. Prop const Navbar. Item = ({ to, on. Click, children }) => { const class. Name = 'navbar-item' if (to) { return ( <Link class. Name={class. Name} to={to}>{children}</Link> ) } if (on. Click) { return ( <button class. Name={class. Name} on. Click={on. Click}>{children}</button> ) } return null } 66

component. From. Prop const enhance = compose( with. Props({ class. Name: 'navbar-item' }), branch(

component. From. Prop const enhance = compose( with. Props({ class. Name: 'navbar-item' }), branch( ({ to }) => to, with. Props({ component: Link }) ), branch( ({ on. Click }) => on. Click, with. Props({ component: 'button' }) ) ) export default enhance(component. From. Prop('component')) 67

component. From. Prop const enhance = compose( with. Props({ class. Name: 'navbar-item' }), branch(

component. From. Prop const enhance = compose( with. Props({ class. Name: 'navbar-item' }), branch( ({ to }) => to, with. Props({ component: Link }) ), branch( ({ on. Click }) => on. Click, with. Props({ component: 'button' }) ) ) export default enhance(component. From. Prop('component')) 68

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. match. params. id } component. Did. Mount() { request. Product(this. props. match. params. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 70

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. match. params. id } component. Did. Mount() { request. Product(this. props. match. params. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 71

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. match. params. id } component. Did. Mount() { request. Product(this. props. match. params. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 72

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. match. params. id } component. Did. Mount() { request. Product(this. props. match. params. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 73

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. id } component. Did. Mount() { request. Product(this. props. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 74

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. id } component. Did. Mount() { request. Product(this. props. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 75

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) class Product. Profile. Container extends Component { should. Component. Update(next. Props) { return next. Props. match. params. id !== this. props. id } component. Did. Mount() { request. Product(this. props. id) } render() { return <Product. Profile product={this. props. product} /> } } export default connect(map. State. To. Props, map. Dispatch. To. Props)(Product. Profile. Container) 76

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) const enhance = compose( only. Update. For. Prop. Types, set. Prop. Types({ product: Product. Shape }), connect(map. State. To. Props, map. Dispatch. To. Props), lifecycle({ component. Did. Mount() { request. Product(this. props. id) } }) ) export default enhance(Product. Profile) 77

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) const enhance = compose( only. Update. For. Prop. Types, set. Prop. Types({ product: Product. Shape }), connect(map. State. To. Props, map. Dispatch. To. Props), lifecycle({ component. Did. Mount() { request. Product(this. props. id) } }) ) export default enhance(Product. Profile) 78

const map. State. To. Props = (state, { match: { params: { id }

const map. State. To. Props = (state, { match: { params: { id } } }) => ({ id, product: get. Product(state, id) }) const enhance = compose( only. Update. For. Prop. Types, set. Prop. Types({ product: Product. Shape }), connect(map. State. To. Props, map. Dispatch. To. Props), lifecycle({ component. Did. Mount() { request. Product(this. props. id) } }) ) export default enhance(Product. Profile) 79

Альтернативы recompose • написать руками? �� • Recompact 38. 2 k. B minified, 6.

Альтернативы recompose • написать руками? �� • Recompact 38. 2 k. B minified, 6. 9 k. B gzipped, � 260 (https: //github. com/neoziro/recompact) • Reassemble 21. 7 k. B minified, 4. 5 k. B gzipped, � 54 (https: //github. com/wikiwi/reassemble) 80

Бенчмарки 100 HOCs, измеряем число обновлений в секунду https: //github. com/neoziro/recompact/tree/master/src/__benchmarks__ 81

Бенчмарки 100 HOCs, измеряем число обновлений в секунду https: //github. com/neoziro/recompact/tree/master/src/__benchmarks__ 81

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count:

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count: products. length }) ) describe('with. Product. Count decorator', () => { const products = [{ id: 1 }] const Mock. Component = () => <div /> it('adds product count prop', () => { const Enhanced = with. Product. Count(Mock. Component) const wrapper = mount(<Enhanced products={products} />) const subject = wrapper. find(Mock. Component) expect(subject. prop('count')). to. Be(1) }) }) 83

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count:

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count: products. length }) ) describe('with. Product. Count decorator', () => { const products = [{ id: 1 }] const Mock. Component = () => <div /> it('adds product count prop', () => { const Enhanced = with. Product. Count(Mock. Component) const wrapper = mount(<Enhanced products={products} />) const subject = wrapper. find(Mock. Component) expect(subject. prop('count')). to. Be(1) }) }) 84

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count:

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count: products. length }) ) describe('with. Product. Count decorator', () => { const products = [{ id: 1 }] const Mock. Component = () => <div /> it('adds product count prop', () => { const Enhanced = with. Product. Count(Mock. Component) const wrapper = mount(<Enhanced products={products} />) const subject = wrapper. find(Mock. Component) expect(subject. prop('count')). to. Be(1) }) }) 85

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count:

Тестирование const with. Product. Count = with. Props( ({ products }) => ({ count: products. length }) ) describe('with. Product. Count decorator', () => { const products = [{ id: 1 }] const Mock. Component = () => <div /> it('adds product count prop', () => { const Enhanced = with. Product. Count(Mock. Component) const wrapper = mount(<Enhanced products={products} />) const subject = wrapper. find(Mock. Component) expect(subject. prop('count')). to. Be(1) }) }) 86

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting:

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting: Prop. Types. string. required, children: Prop. Types. string. required }), only. Update. For. Prop. Types, map. Props(({ greeting, children }) => ({ text: `${greeting}, ${children}` })) ) const Label = ({ text }) => (<h 1>{text}</h 1>) const Greeting. Label = with. Greeting(Label) const App = () => <Greeting. Label greeting="Hi">John</Greeting. Label> 87

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting:

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting: Prop. Types. string. required, children: Prop. Types. string. required }), only. Update. For. Prop. Types, map. Props(({ greeting, children }) => ({ text: `${greeting}, ${children}` })) ) const Label = ({ text }) => (<h 1>{text}</h 1>) const Greeting. Label = with. Greeting(Label) const App = () => <Greeting. Label greeting="Hi">John</Greeting. Label> 88

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting:

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting: Prop. Types. string. required, children: Prop. Types. string. required }), only. Update. For. Prop. Types, map. Props(({ greeting, children }) => ({ text: `${greeting}, ${children}` })) ) const Label = ({ text }) => (<h 1>{text}</h 1>) const Greeting. Label = with. Greeting(Label) const App = () => <Greeting. Label greeting="Hi">John</Greeting. Label> 89

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting:

Отладка const with. Greeting = compose( set. Display. Name('with. Greeting'), set. Prop. Types({ greeting: Prop. Types. string. required, children: Prop. Types. string. required }), only. Update. For. Prop. Types, map. Props(({ greeting, children }) => ({ text: `${greeting}, ${children}` })) ) const Label = ({ text }) => (<h 1>{text}</h 1>) const Greeting. Label = with. Greeting(Label) const App = () => <Greeting. Label greeting="Hi">John</Greeting. Label> 90

Спасибо за внимание! dmitry. a. tsepelev@gmail. com @dmitrytsepelev Dmitry. Tsepelev 93

Спасибо за внимание! dmitry. a. tsepelev@gmail. com @dmitrytsepelev Dmitry. Tsepelev 93