Redux: рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛, рдЬрд┐рдирдХреЗ рднреАрддрд░ рдЬреБрдбрд╝реЗ рд╣реБрдП рдШрдЯрдХ рдирд┐рд╣рд┐рдд рд╣реИрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 10 рдирд╡ре░ 2016  ┬╖  21рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: reduxjs/redux

рдирдорд╕реНрддреЗ, рдпрд╣ рдПрдХ рдореБрджреНрджреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдкреНрд░рд╢реНрди рдХрд╛ рдЕрдзрд┐рдХ рд╣реИред

рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ Redux рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдХреБрдЫ рдореБрджреНрджреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдирд┐рд░реНрдгрд╛рдпрдХ рд╕рдорд╛рдзрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдШрдЯрдХ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдХреБрдЫ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдкрд╣рд▓реЗ рдШрдЯрдХ рдХреЗ рднреАрддрд░ рдПрдХ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдШрдЯрдХ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдореИрдВ рдЕрдВрдд рдореЗрдВ рд╕рд╣рд╛рд░рд╛ рдпрд╛ рд░рд╛рдЬреНрдп (рдпрд╛ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рджреЛрдиреЛрдВ) рд╕реЗ рдЕрд╡рд░реБрджреНрдз рд╣реЛрдиреЗ рд▓рдЧрддрд╛ рд╣реВрдВред рдиреЗрд╕реНрдЯреЗрдб рдШрдЯрдХ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдХреНрдпрд╛ рдПрдХ рдШрдЯрдХ рдХреЛ рдареЛрдХрд░ рдорд╛рд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ рддрд╛рдХрд┐ рдореИрдВ рдХреЗрд╡рд▓ рдЙрд╕ рдШрдЯрдХ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░ рд╕рдХреВрдВ рдЬрд┐рд╕реЗ рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ?

рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдзрдиреНрдпрд╡рд╛рдж

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдпрд╣рд╛рдБ рдЪрд┐рдВрддрд╛ рдХрд╛ рд╡рд┐рд╖рдп рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рдШрдЯрдХ рдЕрдиреНрдп рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рддреЛ рдкреНрд░рддреНрдпрдХреНрд╖ рдмрдЪреНрдЪреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╛ рдХрд╣реАрдВ-рдХрд╣реАрдВ рдкрджрд╛рдиреБрдХреНрд░рдоред рдпрджрд┐ рдЖрдк mount() рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдкреВрд░реНрдг рд░реЗрдВрдбрд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡рдВрд╢рдЬ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ this.context.store рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЗрд╕реЗ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП, рдореБрдЦреНрдп рд╡рд┐рдХрд▓реНрдк рдпрд╛ рддреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡рдВрд╢рдЬ рдЙрдерд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдХреЗ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдЯреЛрд░ рдХреЛ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдХрд░рд╛ рд░рд╣реЗ рд╣реИрдВред

рд╕рднреА 21 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рджреЛ рдЪреАрдЬрд╝реЗрдВ:

1) рдпрд╣ рдЙрдкрдпреЛрдЧ рд╣реИ рдФрд░ рд╢рд╛рдпрдж рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рдвреЗрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

2) connect рдЙрдЪреНрдЪ рдЖрджреЗрд╢ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ
рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдХреЗрд╡рд▓ unconnected рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░
рд╕реНрдЯреЛрд░ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдкрд╛рдЗрдкрд┐рдВрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдбрдХреНрд╕ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░реЗрдВ рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

рдпрджрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреЛрд╕реНрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

рдХреБрдЫ рд╡рд┐рдЪрд╛рд░:

  • рд╕рд┐рд░реНрдл рдПрдХ рдШрдЯрдХ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ "рдЙрдерд▓реЗ" рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рд╕реА рднреА рдмрдЪреНрдЪреЗ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ
  • рдЖрдк рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ <Provider store={testStore}><ConnectedComponent /></Provider> рднреА рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

FYI рдХрд░реЗрдВ, рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣рд╛рдБ рдкрд░ React / Redux рдкрд░реАрдХреНрд╖рдг рдкрд░ рдХрдИ рд▓реЗрдЦреЛрдВ рдХреЗ рд▓рд┐рдВрдХ рд╣реИрдВ, рдЬреЛ рдЖрдкрдХреЛ рдорджрджрдЧрд╛рд░ рдорд┐рд▓ рд╕рдХрддреЗ рд╣реИрдВ: https://github.com/markerikson/react-redux-links/blob/master/react-redux-testingред md ред

рдФрд░ рд╣рд╛рдБ, рдПрдХ рдЙрдкрдпреЛрдЧ рдкреНрд░рд╢реНрди рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╣реАрдВ рдФрд░ рдмреЗрд╣рддрд░ рдкреВрдЫрд╛ рдЧрдпрд╛ рд╣реИред

рдзрдиреНрдпрд╡рд╛рдж @markerikson рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрддрд╛рдП рдЧрдП рдЙрддреНрддрд░рд╛рд░реНрдз рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЗ рд▓рд┐рдВрдХ рдХреА рд╕реВрдЪреА рдХреЛ рднреА рдмреБрдХрдорд╛рд░реНрдХ рдХрд░ рджреЗрдЧрд╛ :)

рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ рдПрдХ рдмрд╛рд░ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдРрд╕рд╛ рдХреБрдЫ рдХрд░рдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИрдВ

// Component.js
import React from 'react'

export const Component = ({ a, b, c }) => ( 
  // ...
)

// ...

export default connect(mapStateToProps, mapDispatchToProps)(Component)

рддреЛ рдЖрдк рдмрд╕ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЬреБрдбрд╝реЗ рд╕реЗ рдкрд╣рд▓реЗ рдШрдЯрдХ рдореЗрдВ рд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ

// Component.spec.js
import { Component } from './Component.js'
import { mount } from 'enzyme'

it('should mount without exploding', () => {
  mount(<Component a={1} b={2} c={3} />)
})

рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╕реНрдЯреЛрд░ рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдкрд░рд┐рд╡рд░реНрддрди рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рдЪрд╛рд░рд┐рдд рд╣реЛ рд░рд╣реЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ Provider рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдЕрд▓рдЧ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореВрд▓реНрдп рдорд┐рд▓рддрд╛ рд╣реИред

рдпрд╣рд╛рдБ рдЪрд┐рдВрддрд╛ рдХрд╛ рд╡рд┐рд╖рдп рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рдШрдЯрдХ рдЕрдиреНрдп рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рддреЛ рдкреНрд░рддреНрдпрдХреНрд╖ рдмрдЪреНрдЪреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╛ рдХрд╣реАрдВ-рдХрд╣реАрдВ рдкрджрд╛рдиреБрдХреНрд░рдоред рдпрджрд┐ рдЖрдк mount() рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдкреВрд░реНрдг рд░реЗрдВрдбрд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡рдВрд╢рдЬ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ this.context.store рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЗрд╕реЗ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП, рдореБрдЦреНрдп рд╡рд┐рдХрд▓реНрдк рдпрд╛ рддреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡рдВрд╢рдЬ рдЙрдерд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдХреЗ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдЯреЛрд░ рдХреЛ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдХрд░рд╛ рд░рд╣реЗ рд╣реИрдВред

@markerikson рдЖрд╣ рдареАрдХ рд╣реИ, рдореИрдВ рдмрд╕ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рд╛ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдУрдкреА рдмрд╛рд╣рд░реА рдХреЗ рдмрдЬрд╛рдп рдЖрдВрддрд░рд┐рдХ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ред ЁЯСН

рдЖрдкрдХреА рдорджрдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдЕрдм рддрдХ рд▓реЛрдЧ,

рдЗрд╕ рд╕рдордп рдореЗрд░рд╛ рдЬреЛ рдореБрдЦреНрдп рдореБрджреНрджрд╛ рд╣реИ, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рд░рд╛рдЬреНрдп рд╕реЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рднреАрддрд░ рдирд┐рд╣рд┐рдд рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рджреГрд╢реНрдп рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдореЙрдХрд┐рдВрдЧ рдЕрд╡рд╕реНрдерд╛ рд╡рд╣ рдЪреАрдЬ рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдлреА рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХреБрдЫ рднреА рдирд┐рд░реНрдгрд╛рдпрдХ рдирд╣реАрдВ рдкрд╛ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЕрдЧрд░ рдХреЛрдИ рдореБрдЭреЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рджреЗ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рдирдХрд▓реА рд░рд╛рдЬреНрдп рдХреЛ рдХреИрд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░реВрдВрдЧрд╛? рдиреЗрд╕реНрдЯреЗрдб рдХрдиреЗрдХреНрдЯреЗрдб рдпрд╛ рдЙрдЪреНрдЪрддрд░ рдСрд░реНрдбрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ?

рддрд┐рдпрд╛

@StlthyLee : "рдкрд╛рд╕ рдж рд╕реНрдЯреЗрдЯ" рд╕реЗ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ? рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ <Provider store={store}><ComponentWithConnectedDescendants /></Provider> рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрд╕реЗ рдЪреАрдЬреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ, рдЗрд╕реЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдШрдЯрдХ рдиреЗрд╕реНрдЯреЗрдб рдХреЛ рдЖрд╡реЗрджрди рд░рд╛рдЬреНрдп рд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдХрд╛рд░рдг рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИред

@StlthyLee рдХреЛ рд╢рд╛рдпрдж рдПрдХ рдЙрджрд╛рд╣рд░рдг / рдЬрд┐рд╕реНрдЯ / рдХреЛрдбрдкреЗрди / рд░реЗрдкреЛ-рд▓рд┐рдВрдХ рдпрд╛ рдХреБрдЫ рдФрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реНрдкреЙрдЯ рдХрд░рдиреЗ рдореЗрдВ рдХрдо рд╕рдордп рд▓рдЧреЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣рд╛рдВ рд╢рдмреНрджрд╛рд╡рд▓реА рдХреНрд▓реИрд╢ рд╣реЛрдиреЗ рд▓рдЧрддреЗ рд╣реИрдВред

@ рдХреЛрд▓реЛрдХ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛

https://gist.github.com/StlthyLee/02e116d945867a77c382fa0105af1bf3

рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреГрдкрдпрд╛ рдкреВрдЫреЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдРрд╕реА рдЪреАрдЬ рд╣реИ рдЬрд┐рд╕рдХреА рдореИрдВ рддрд╣ рддрдХ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реВрдВ, рдкрд┐рдЫрд▓реЗ 9-10 рд╕рд╛рд▓ рд░реЗрд▓ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдФрд░ рдЙрд╕ рдирдЬрд░рд┐рдП рд╕реЗ рдЯреАрдбреАрдбреА рдХреА рдЕрдЪреНрдЫреА рд╕рдордЭ рд░рдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЕрдм рдЗрд╕реЗ рдкрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ / Redux рджреБрдирд┐рдпрд╛ рдореЗрдВ TDD рдХреЗ рдЖрд╕рдкрд╛рд╕ рдореЗрд░рд╛ рд╕рд┐рд░ред

рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдореИрдВ рдЕрдм рдЗрд╕ рдореБрджреНрджреЗ рдХреА рддрд╣ рддрдХ рдкрд╣реБрдБрдЪ рдЧрдпрд╛ рд╣реВрдБ, рдпрд╣ рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдореБрджреНрджрд╛ рдирд╣реАрдВ рдерд╛, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдЕрдиреНрдп рдЯреАрдо рдХреЗ рд╕рджрд╕реНрдп рджреНрд╡рд╛рд░рд╛ рдХреА рдЧрдИ рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдФрд░ рдкрд┐рдЫрд▓реА рддреНрд░реБрдЯрд┐ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рд░реНрд╕рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдореЗрд░реЗ рдкрд╕рдВрджреАрджрд╛ TDD рддрд░реАрдХреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдХреЛрдб рдХреЛ рдлрд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгред рдпрд╣рд╛рдБ рджреА рдЧрдИ рд╕рднреА рд╕реВрдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдпрд╣ рдЕрддреНрдпрдВрдд рдореВрд▓реНрдпрд╡рд╛рди рд╣реИ

рдмрд╕ рдПрдХ рдФрд░ рд╡рд┐рдХрд▓реНрдк рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛ред рдПрдХ рдирдХрд▓реА рд╕реНрдЯреЛрд░ рдмрдирд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдХреЗ рдЧреИрд░-рдЬреБрдбрд╝реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдПрдХ рд╕реНрдЯреЛрд░ рдХреЗ рдмрд┐рдирд╛ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

class TopLevelImpl extends React.PureComponent {
  // Implementation goes here
}

// Export here for unit testing.  The unit test imports privates and uses TopLevel
// with Enzyme's mount().
export const privates = {
  TopLevel: TopLevelImpl,
}

export const TopLevel = connect(mapStateToProps)(TopLevelImpl)

рдореИрдВрдиреЗ рдмрдЪреНрдЪреЗ рдХреЛ рдиреЗрд╕реНрдЯреЗрдб рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдХрд╛рдо рдХрд┐рдпрд╛ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛред

рдлрд┐рд░ рдореИрдВрдиреЗ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ рд▓рд┐рдпрд╛ рдФрд░ рдмрдЪреНрдЪреЗ рд╕реЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдРрдк рдХреЗ render() рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкреНрд░реЙрдкреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ред рдЬрдм рдЗрдХрд╛рдИ рд╢реАрд░реНрд╖ рд╕реНрддрд░ рдХреЗ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реА рд╣реИ, рддреЛ рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирдХрд▓реА рдШрдЯрдХреЛрдВ рдореЗрдВ рдЧреБрдЬрд░рддрд╛ рд╣реВрдВ рдХрд┐ рд╡реЗ рд╕рд╣реА рдЬрдЧрд╣ рдкрд░ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╣реИрдВред рдЖрдк рдЧреИрд░-рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рднреА рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

// Root render function
render() {
  return (
    <Provider store={store}>
      <TopLevel child1={<Child1 />} child2={<Child2 />} />
    </Provider>
  )
}

рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдкрдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкрд╕рдВрдж рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдРрд╕рд╛ рдХреБрдЫ рдХрд░рддрд╛ рд╣реВрдВ

const props = {
  child1: () => (<div />),
  child2: () => (<div />)
}
<TopLevel {...props} />

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЪрд╛рдЗрд▓реНрдб 1 рдФрд░ рдЪрд╛рдЗрд▓реНрдб 2 рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рддреЛ рд╕рдВрднрд╡рддрдГ рдЙрдиреНрд╣реЗрдВ рдЖрдкрдХреЗ рдЯреЙрдкрд▓реЗрд╡рд▓ рдШрдЯрдХ рдореЗрдВ рд╣реЛрдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдореИрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рднреА рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ рдЕрдЧрд░ рдореБрдЭреЗ рдШрдЯрдХ рдХреЛ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдореИрдВ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЖрдкрдХреЗ рдЕрдВрддрд┐рдо рд╡рд╛рдХреНрдп рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░рддрд╛ред рдХрд┐рд╕реА рдЕрдиреНрдп рдШрдЯрдХ рдореЗрдВ рдмрд╛рд▓ рдШрдЯрдХреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?

рдХреБрдВрдЖред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рдмрд╛рд╣рд░реА рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдШрдЯрдХ рд╣реИ рдЬреЛ рдПрдХ рдпрд╛ рдХреБрдЫ рдЖрдВрддрд░рд┐рдХ рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдЧрд░ рдореИрдВ рдмрд╛рд╣рд░реА рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рддреЛ рдореИрдВ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВ

wrapper = mount(<ExternalComponent.WrappedComponent {...props} />)

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореБрдЭреЗ рддреНрд░реБрдЯрд┐ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдЖрдВрддрд░рд┐рдХ рдШрдЯрдХреЛрдВ рдХреЛ рдареАрдХ рд╕реЗ рдЪрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╛рдЬреНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

Invariant Violation: Could not find "store" in either the context or props

рдлрд┐рд░ рдореИрдВрдиреЗ рдирдХрд▓реА рд░рд╛рдЬреНрдп рдЖрджрд┐ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдореБрдЭреЗ рд╣рд░ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реЗ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХрд░рдиреЗ рдкрдбрд╝рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдПрд╕рд┐рдВрдХреНрд╕ рдХреЙрд▓, рдЗрдирд┐рд╢рд┐рдпрд▓рд╕реНрдЯреЗрдЯ рдЖрджрд┐ рдФрд░ рдореБрдЭреЗ рдЗрд╕рд╕реЗ рдЬреБрдбрд╝реА рдЕрдиреНрдп рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдереАрдВред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рднреА рдЖрдВрддрд░рд┐рдХ рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЙрдЪрд┐рдд рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдУрд╡рд░рдХрд┐рд▓ рд╣реЛрдЧрд╛, рдЕрдЧрд░ рдореИрдВ рд╕рд┐рд░реНрдл рдмрд╛рд╣рд░реА рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд╕рднреА рдЬреБрдбрд╝реЗ рд╣реБрдП рдШрдЯрдХреЛрдВ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрд╛рд╣рд░реА рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИред рдФрд░ рдЕрдм рдореИрдВ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдЦрд╛рд▓реА рдбрд┐рд╡ рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддрд╛ рд╣реВрдВ рдЬрдм рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рдЕрд░реЗ рд╣рд╛рдБ, рдпрд╣ рдкреИрдЯрд░реНрди рдХреЗ рд▓рд┐рдП рд╕рд┐рд░реНрдл рдореВрд▓ рдкреНрд░реЗрд░рдгрд╛ рдереАред рддреЛ рдЕрдкрдиреА рд╕рдЬрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХрд╛ рдорддрд▓рдм рдерд╛ "рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЪрд╛рдЗрд▓реНрдб 1 рдФрд░ рдЪрд╛рдЗрд▓реНрдб 2 рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдЯреЙрдкрд▓реЗрд╡рд▓ рдШрдЯрдХ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред"

рдорд╛рдирд╛ред

@StlthyLee , рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореБрдЭреЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдЬрдм рдПрдХ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЬреБрдбрд╝реЗ рд╣реБрдП рдШрдЯрдХ рд╣реЛрддреЗ рд╣реИрдВред

рдПрдХ рд╕рдорд╛рдзрд╛рди рдЬреЛ рдореБрдЭреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рд▓рдЧрд╛ рд╡рд╣ рд╣реИ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдиреЗрд╕реНрдЯреЗрдб рдШрдЯрдХ рдХреЛ рд░рд┐рдбреНрдпреВрдХреНрд╕ рд╕реНрдЯреЛрд░ рд╕реЗ рдЬреЛрдбрд╝рдирд╛ред

  • рдЬрдм рдкрд░реАрдХреНрд╖рдг рдЪрд▓рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ NODE_ENV="test" рд╕реЗрдЯрдЕрдк рдХрд░реЗрдВред рдЖрдк рдЗрд╕ рдЪрд░ рдХреЛ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдШрдЯрдХ рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЧреБрдг рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдШрдЯрдХ рд╕реНрдЯреЛрд░ рд╕реЗ рдЬреБрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдореВрд▓ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред
  • рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдШрдЯрдХ рдХреЛ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдмрдирд╛рддреЗ рд╣реИрдВред рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдШрдЯрдХ рдХреЛ рдЪрд▓рд╛рддреЗ рд╕рдордп рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИред

рдХ) рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рд╡рд░рдг test :

export default function ifTestEnv(forTestEnv, forNonTestEnv) {
  const isTestEnv = process && process.env && process.env.NODE_ENV === 'test';
  const hoc = isTestEnv ? forTestEnv : forNonTestEnv;
  return function(component) {
    return hoc(component);
  };
}

рдмреА) рдЕрдЧрд▓рд╛, рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ defaultProps() рдФрд░ connect() рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import defaultProps from 'recompose/defaultProps';

import ifTestEnv from 'helpers/if_test_env';
import { fetch } from './actions';

class MyComponent extends Component {
   render() {
      const { propA, propB } = this.props;
      return <div>{propA} {probB}</div>
   }

   componentDidMount() {
      this.props.fetch();
   }
}

function mapStateToProps(state) {
  return {
    propA: state.valueA,
    propB: state.valueB
  };
}

export default ifTestEnv(
  defaultProps({
    propA: 'defaultA',
    propB: 'defaultB',
    fetch() {   }
  }),
  connect(mapStateToProps, { fetch })
)(MyComponent);

рдЧ) рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдкрд░ NODE_ENV "test" :

  • рдореЛрдЪрд╛ рд╕реАрдПрд▓рдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрд╕рд░реНрдЧ рд▓рдЧрд╛рдПрдВ: NODE_ENV='test' mocha app/**/*.test.jsx ред
  • рд╡реЗрдмрдкреИрдХ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рдкреНрд▓рдЧрдЗрди рд▓рд╛рдЧреВ рдХрд░реЗрдВ:
plugins: [
    // plugins...
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('test')
      },
    })
]

@markerikson рджреЛ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореИрдВрдиреЗ рджреВрд╕рд░рд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдФрд░ рдкреНрд░рджрд╛рддрд╛ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЛ рд▓рдкреЗрдЯрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ mapStateToProps рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ mapDispatchToProps рд╕рд╛рде рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдорд┐рд▓рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рдШрдЯрдХ рдЕрдиреНрдп рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред

рдореЗрд░рд╛ MapDispatchToProps рдХреБрдЫ рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ

/* <strong i="10">@flow</strong> */
import { bindActionCreators } from 'redux';

import type { Dispatch } from './types';
import * as actions from './actions';

export default (dispatch: Dispatch, ownProps: Object): Object => ({
  actions: bindActionCreators(actions, dispatch),
});

рдпрд╣рд╛рдВ рд▓реМрдЯрд╛рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдореВрд▓реНрдп undefined ред

store.js

import { applyMiddleware, compose, createStore } from 'redux';
import { autoRehydrate } from 'redux-persist';
import thunk from 'redux-thunk';

import rootReducer from './reducers';
import { REHYDRATE } from 'redux-persist/constants';

const store = compose(autoRehydrate(), applyMiddleware(thunk, createActionBuffer(REHYDRATE)))(createStore)(rootReducer);

export default store;

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдлреА рдкреБрд░рд╛рдирд╛ рдзрд╛рдЧрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рдЙрдкрджреНрд░рд╡ рдХреЗ рдореБрджреНрджреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдпрд╛ рдФрд░ рд╕реЛрдЪрд╛ рдХрд┐ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрд┐рд╕реА рдРрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдХреА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рдзрд╛рдЧреЗ рдкрд░ (рдореЗрд░реА рддрд░рд╣) рдареЛрдХрд░ рдЦрд╛рддрд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Redux рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рдерд╛, рдПрдХ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди рдЬреЛ рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдХрдиреЗрдХреНрдЯ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЗрд╡рд▓ рдЕрдирдЫреБрдП рдШрдЯрдХ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЬреИрд╕реЗ рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдШрдЯрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:


export class ExampleApp extends Component {
  render() {
  }
}

export default connect(
  null,
  { someAction }
)(ExampleApp);

рдлрд┐рд░ рдЕрдкрдиреА рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЖрдк рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЗ рд╕рд╛рде Redux рдмрд╛рддрдЪреАрдд рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдХрд▓реА рдХрдиреЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

jest.mock("react-redux", () => {
  return {
    connect: (mapStateToProps, mapDispatchToProps) => (
      ReactComponent
    ) => ReactComponent
  };
});

рдЗрд╕ рдореЙрдХрд┐рдВрдЧ рдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдПрдХ рдЬреБрдбрд╝реЗ рд╣реБрдП рдмрдЪреНрдЪреЗ рдХреА рдирдХрд▓ рдХрд░рддрд╛ рд╣реИред

@scottbanyard рдЖрдк рдмрдЪреНрдЪреЗ рдХреЗ рдШрдЯрдХ рдХреЛ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

mickeyreiss-visor picture mickeyreiss-visor  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jimbolla picture jimbolla  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

CellOcean picture CellOcean  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ms88privat picture ms88privat  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rui-ktei picture rui-ktei  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ