Redux: рдХрдиреЗрдХреНрдЯ рдХрд╛ рдЕрдиреБрд╢рдВрд╕рд┐рдд рдЙрдкрдпреЛрдЧ ()

рдХреЛ рдирд┐рд░реНрдорд┐рдд 7 рдЕрдЧре░ 2015  ┬╖  34рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: reduxjs/redux

рд╣рд╛рдп @gaearon - рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рдкрдврд╝рддреЗ рд╕рдордп рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдерди рдиреЗ рдореБрдЭреЗ рдЪреМрдХрд╛ рджрд┐рдпрд╛:

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

рдбреАрдк рдкреНрд░реЛрдк рдЪреЗрди рд░рд┐рдПрдХреНрдЯ рдХреЗ рдореБрджреНрджреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдерд╛ рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдлреНрд▓рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛; рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реЗрдбрдСрдлрд╝ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдкреНрд░реЛрдк рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕реЗрдЯрдЕрдк/рдмрдирд╛рдП рд░рдЦрдиреЗ/рдЯреНрд░реЗрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд╕реЗ рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдЕрдкрдиреЗ рдмрдЪреНрдЪреЛрдВ рдХреА рдбреЗрдЯрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ред рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рд╕реЗ, рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реВрдВ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ: рдореБрд╕реНрдХрд╛рди:

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

рдХреНрдпрд╛ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ () рдХреЗ рджреМрд░рд╛рди рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рдЬреБрд░реНрдорд╛рдирд╛ рд╣реЛрдЧрд╛?

рдирд╣реАрдВ, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд┐рдкрд░реАрдд рд╣реИ: рдЖрдк рдЯреЙрдк-рдбрд╛рдЙрди рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдЫреЛрдбрд╝ рдХрд░ рдмреЗрд╣рддрд░ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред

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

рдореИрдВ рдмреНрд░реЗрдВрдЯ рд╕реЗ рджреГрдврд╝рддрд╛ рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред рдпрд╣ рд░рд┐рд▓реЗ рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рдкреАрдЫреЗ рдХреА рдореВрд▓рднреВрдд рд╕реЛрдЪ рдереА рдФрд░ рдЙрдЪреНрдЪ рд╕рд╛рдордВрдЬрд╕реНрдп рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИред

рд╢рд╛рдпрдж рд╣рдореЗрдВ рд╕рд┐рд░реНрдл рдпрд╣ рдХрд╣рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ "рдпрд╣рд╛рдВ рд▓реЛрдЧреЛрдВ рдХреА рдЕрд▓рдЧ рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдПрдВ рд╣реИрдВ"ред

@gaearon - рд╢рд╛рдпрдж рдЯреНрд░реЗрдбрдСрдлрд╝ рдкрд░ рдПрдХ рдЦрдВрдб рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдХреИрд╕реЗ рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдореИрдВ рдЙрд╕рдХреЗ рд▓рд┐рдП рд╡рд░реАрдпрддрд╛рдУрдВ рдХреЗ рдЕрдкрдиреЗ рдкрдХреНрд╖ рдореЗрдВ рдкрд┐рдЪ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред

рдардВрдбрд╛ред рдЖрдЗрдП рдЗрд╕реЗ рдЦреБрд▓рд╛ рд░рдЦреЗрдВ рдФрд░ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдлрд┐рд░ рд╕реЗ рджреЗрдЦреЗрдВред

рдЕрдЪреНрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИ @gaearon! :) рдореБрдЭреЗ рдкрд┐рдВрдЧ рдХрд░реЗрдВ рдЬрдм рдЖрдк рдлрд┐рд░ рд╕реЗ рдЖрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ

рдореИрдВ Redux рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдирдпрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ рдХреЗ рджреМрд░рд╛рди рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рджрд░реНрдж рдмрд┐рдВрджреБ рд░рд╣рд╛ рд╣реИ, рдПрдХ рдРрдк рдмрдирд╛рдирд╛ рдЬрд╣рд╛рдВ рд╣рдордиреЗ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдХрд╛рдлреА рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИред рддреЛ рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдкрд░ @brentvatne рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред

рдХреНрдпрд╛ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ () рдХреЗ рджреМрд░рд╛рди рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рдЬреБрд░реНрдорд╛рдирд╛ рд╣реЛрдЧрд╛?

рдХреНрдпрд╛ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ () рдХреЗ рджреМрд░рд╛рди рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рдЬреБрд░реНрдорд╛рдирд╛ рд╣реЛрдЧрд╛?

рдирд╣реАрдВ, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд┐рдкрд░реАрдд рд╣реИ: рдЖрдк рдЯреЙрдк-рдбрд╛рдЙрди рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдЫреЛрдбрд╝ рдХрд░ рдмреЗрд╣рддрд░ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред

рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдордзреНрдп-рд╕реНрддрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреБрди: рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг рд╕реЗ рдмрдЪ рд╕рдХрддреЗ рд╣реИрдВ?

рд╣рд╛рдВред

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

рдПрдХ рдореЛрдЯрд╛ рдЙрджрд╛рд╣рд░рдг рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП:

рдлреВ.рдЬреЗрдПрд╕рдПрдХреНрд╕

export class Foo extends Component {
  render () {
    return (
      <div className='foo'>
        {/* foo stuff going on in here */}
        {this.props.Bar}
      </div>
    )
  }
}

FooContainer.jsx

@connect(getState, getActions)
export class FooContainer extends Component {
  render () {
    return (
      <Foo
        Bar={<BarContainer/>}
        {...this.props}
       />
    )
  }
}

@brentvatne рдЕрдЧрд░ рдЖрдкрдХреЛ рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдорди рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ рдХрд┐ рдЗрд╕реЗ рд╡рд░реНрддрдорд╛рди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдХрд╣рд╛рдВ рдлрд┐рдЯ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдФрд░ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ! :-)

2015/10/19 рдЕрджреНрдпрддрди: рдореИрдВрдиреЗ рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ react-redux-provide рд░реВрдк рдореЗрдВ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рд╣реИред рдиреАрдЪреЗ рджреЗрдЦреЗрдВ https://github.com/rackt/redux/issues/419#issuecomment -149325401ред

#475 рд╕реЗ рдЬрд╛рд░реА, рдореИрдВ рд╡рд░реНрдгрди рдХрд░реВрдБрдЧрд╛ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рд▓реЗрдХрд░ рдЖрдпрд╛ рд╣реВрдБ, рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдЪрд░реНрдЪрд╛ рд╢рд╛рдпрдж рдЕрдм react-redux ред ;)

рдмрдЧрд╝рд▓ рдореЗрдВ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдореЙрдбреНрдпреВрд▓рд░ рдкреНрд░рджрд╛рддрд╛

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

рддреЛ... рдореБрдЭреЗ actions , constants , containers , reducers , рдФрд░ stores рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓ рдЧрдпрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рднреАрддрд░ рд╕рд╛рдорд╛рдиреНрдп ) рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдПрдХрд▓ providers рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ред рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, providers рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЖрд╡рд╢реНрдпрдХ рднреА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЛ рдкреИрдХ рдФрд░ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рд╡рд┐рд╢реЗрд╖ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдкрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреБрдЫ рд╡рд╛рдХрдИ рдЕрдЪреНрдЫреА рдЪреАрдЬреЗрдВ рд╕рд╛рдордиреЗ рдЖрддреА рд╣реИрдВ !! (рдиреЛрдЯ: рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдПрдХ рдореЗрдВ рд╕рдореЗрдХрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рд▓рдЧрддрд╛ рд╣реИ 1) рдЪреАрдЬреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ/рд╕рдордЭрдиреЗ рдореЗрдВ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ 2) рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИ рдФрд░ 3) рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рджрд╛рддрд╛ рдЗрддрдиреЗ рдЫреЛрдЯреЗ рд╣реЛрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред )

рдЙрджрд╛рд╣рд░рдг "рдЧреВрдВрдЧрд╛" рдШрдЯрдХ

// components/Branch.js

import React, { Component } from 'react';
import provide from '../utilities/provide.js';
import { branchName, tree, toggle, open, theme } from '../common/propTypes.js';
import Limbs from './Limbs.js';

<strong i="22">@provide</strong>  // maybe require specifying expected props? e.g., @provide('theme')
export default class Branch extends Component {
  static propTypes = { branchName, tree, toggle, open, theme };

  onClick(event) {
    const { branchName, toggle } = this.props;  // toggle is from a provider

    event.stopPropagation();
    toggle(branchName);
  }

  render() {
    const props = this.props;
    const { branchName, tree, open, theme } = props;  // latter 3 from providers
    const classes = theme.sheet.classes || {};
    const imgSrc = open ? 'folder-open.png' : 'folder-closed.png';

    return (
      <div
        onClick={::this.onClick}
        className={classes.branch}
      >
        <h4 className={classes.branchName}>
          <img
            className={classes.branchIcon}
            src={theme.imagesDir+imgSrc}
          />

          <span>{branchName}</span>
        </h4>

        <Limbs
          tree={tree}
          open={open}
        />
      </div>
    );
  }
}

рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рддрд╛

// providers/toggle.js

import createProvider from '../utilities/createProvider.js';

export const TOGGLE = 'TOGGLE';

export const actions = {
  toggle(fullPath) {
    return { type: TOGGLE, fullPath };
  }
};

export const reducers = {
  open(state = {}, action) {
    switch (action.type) {
      case TOGGLE:
        const { fullPath } = action;
        return { ...state, [fullPath]: !state[fullPath] };

      default:
        return state;
    }
  }
};

function merge (stateProps, dispatchProps, parentProps) {
  return Object.assign({}, parentProps, {
    open: !!stateProps.open[parentProps.fullPath]
  });
}

export const provider = createProvider(actions, reducers, merge);
export default provider;

рдмрдЧрд╝рд▓ рдореЗрдВ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ

рдЬреИрд╕рд╛ рдХрд┐ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╡рд┐рдЪрд╛рд░ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЛ "рдЧреВрдВрдЧрд╛" рдШрдЯрдХреЛрдВ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рд╣реИред рддреЛ рдЕрдкрдиреЗ рдРрдк рдХреЛ рдорд╛рдЙрдВрдЯ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

import React from 'react';
import { Provider } from 'react-redux';

import assignProviders from './utilities/assignProviders.js';
import createStoreFromProviders from './utilities/createStoreFromProviders.js';

import dark from './themes/dark.js';
import github from './sources/github.js';
import * as providers from './providers/index.js';
import * as components from './components/index.js';

const { packageList, sources, toggle, theme } = providers;
const { Branches, Branch, Limbs, Limb } = components;

const initialState = {
  packageList: [
    'github:gaearon/react-redux<strong i="10">@master</strong>',
    'github:loggur/branches<strong i="11">@master</strong>',
    'github:rackt/redux<strong i="12">@master</strong>'
  ],
  sources: {
    github: github({
      token: 'abc123',
      auth: 'oauth'
    })
  },
  open: {
    'github': true,
    'github:gaearon': true,
    'github:gaearon/react-redux<strong i="13">@master</strong>': true,
    'github:rackt': true,
    'github:rackt/redux<strong i="14">@master</strong>': true
  },
  theme: dark
};

const store = createStoreFromProviders(providers, initialState);

assignProviders({ theme }, components);
assignProviders({ packageList }, { Branches });
assignProviders({ sources }, { Branches, Branch });
assignProviders({ toggle }, { Branch, Limb });

React.render(
  <Provider store={store}>
    {() => <Branches/>}
  </Provider>,
  document.getElementById('root')
);

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

рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб

рдЖрдк рд╢рд╛рдпрдж рдЗрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдХреБрдЫ рдореБрдЯреНрдареА рднрд░ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реБрдП рджреЗрдЦреЗрдВрдЧреЗред рдпреЗ рдЫреЛрдЯреЗ рдореЙрдбреНрдпреВрд▓ рд╣реИрдВ (рдЪрд╛рд░ рдореЗрдВ рд╕реЗ 3 рдХреЗрд╡рд▓ рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпрд╛рдВ рд▓рдВрдмреА рд╣реИрдВ) рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдореМрдЬреВрджрд╛ redux рдФрд░ react-redux рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдпреЛрдЬрди рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдмрд╕реЗ рдЖрдо рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рддрдХ рд╣реА рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИрдВред рд╡реЗ рдХреЗрд╡рд▓ рдЪреАрдЬреЛрдВ рдХреЛ рдФрд░ рднреА рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдореМрдЬреВрдж рд╣реИрдВред

// utilities/createProvider.js

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

/**
 * Creates an object to be used as a provider from a set of actions and 
 * reducers.
 *
 * <strong i="10">@param</strong> {Object} actions
 * <strong i="11">@param</strong> {Object} reducers
 * <strong i="12">@param</strong> {Function} merge Optional
 * <strong i="13">@return</strong> {Object}
 * <strong i="14">@api</strong> public
 */
export default function createProvider (actions, reducers, merge) {
  return {
    mapState(state) {
      const props = {};

      for (let key in reducers) {
        props[key] = state[key];
      }

      return props;
    },

    mapDispatch(dispatch) {
      return bindActionCreators(actions, dispatch);
    },

    merge
  };
}
// utilities/createStoreFromProviders.js

import { createStore, combineReducers } from 'redux';

import { createStore, applyMiddleware, combineReducers } from 'redux';

/**
 * Creates a store from a set of providers.
 *
 * <strong i="17">@param</strong> {Object} providers
 * <strong i="18">@param</strong> {Object} initialState Optional
 * <strong i="19">@return</strong> {Object}
 * <strong i="20">@api</strong> public
 */
export default function createStoreFromProviders (providers, initialState) {
  const reducers = {};
  const middleware = [];
  let create = createStore;

  for (let key in providers) {
    let provider = providers[key];

    Object.assign(reducers, provider.reducers);

    if (provider.middleware) {
      if (Array.isArray(provider.middleware)) {
        for (let mid of provider.middleware) {
          if (middleware.indexOf(mid) < 0) {
            middleware.push(mid);
          }
        }
      } else if (middleware.indexOf(provider.middleware) < 0) {
        middleware.push(provider.middleware);
      }
    }
  }

  if (middleware.length) {
    create = applyMiddleware.apply(null, middleware)(createStore);
  }

  return create(combineReducers(reducers), initialState);
}
// utilities/assignProviders.js

/**
 * Assigns each provider to each component.  Expects each component to be
 * decorated with `@provide` such that it has an `addProvider` static method.
 *
 * <strong i="5">@param</strong> {Object} providers
 * <strong i="6">@param</strong> {Object} components
 * <strong i="7">@api</strong> public
 */
export default function assignProviders (providers, components) {
  for (let providerName in providers) {
    let provider = providers[providerName];

    if (provider.default) {
      provider = provider.default;
    } else if (provider.provider) {
      provider = provider.provider;
    }

    for (let componentName in components) {
      let addProvider = components[componentName].addProvider;
      if (typeof addProvider === 'function') {
        addProvider(providerName, provider);
      }
    }
  }
}

рдФрд░ рдЕрдВрддрд┐рдо рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ provide рдбреЗрдХреЛрд░реЗрдЯрд░ рд╣реИред рдпрд╣ connect рдХрд╛ рдПрдХ рд╕рдВрд╢реЛрдзрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИ рдЬрд┐рд╕реЗ рд╕рд╛рдЗрдбрд╡реЗрдЬ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

// utilities/provide.js

import React, { Component, PropTypes } from 'react';
import createStoreShape from 'react-redux/lib/utils/createStoreShape';
import shallowEqual from 'react-redux/lib/utils/shallowEqual';
import isPlainObject from 'react-redux/lib/utils/isPlainObject';
import wrapActionCreators from 'react-redux/lib/utils/wrapActionCreators';
import invariant from 'invariant';

const storeShape = createStoreShape(PropTypes);
const defaultMapState = () => ({});
const defaultMapDispatch = dispatch => ({ dispatch });
const defaultMerge = (stateProps, dispatchProps, parentProps) => ({
  ...parentProps,
  ...stateProps,
  ...dispatchProps
});

// Helps track hot reloading.
let nextVersion = 0;

export default function provide (WrappedComponent) {
  const version = nextVersion++;
  const providers = [];
  let shouldSubscribe = false;

  function getDisplayName () {
    return ''
      +'Provide'
      +(WrappedComponent.displayName || WrappedComponent.name || 'Component')
      +'('+providers.map(provider => provider.name).join(',')+')';
  }

  function addProvider (name, { mapState, mapDispatch, merge }) {
    if (Boolean(mapState)) {
      shouldSubscribe = true; 
    }

    providers.push({
      name,
      mapState: mapState || defaultMapState,
      mapDispatch: isPlainObject(mapDispatch)
        ? wrapActionCreators(mapDispatch)
        : mapDispatch || defaultMapDispatch,
      merge: merge || defaultMerge
    });

    Provide.displayName = getDisplayName();
  }

  function computeStateProps (store) {
    const state = store.getState();
    const stateProps = {};

    for (let provider of providers) {
      let providerStateProps = provider.mapState(state);

      invariant(
        isPlainObject(providerStateProps),
        '`mapState` must return an object. Instead received %s.',
        providerStateProps
      );

      Object.assign(stateProps, providerStateProps);
    }

    return stateProps;
  }

  function computeDispatchProps (store) {
    const { dispatch } = store;
    const dispatchProps = {};

    for (let provider of providers) {
      let providerDispatchProps = provider.mapDispatch(dispatch);

      invariant(
        isPlainObject(providerDispatchProps),
        '`mapDispatch` must return an object. Instead received %s.',
        providerDispatchProps
      );

      Object.assign(dispatchProps, providerDispatchProps);
    }

    return dispatchProps;
  }

  function computeNextState (stateProps, dispatchProps, parentProps) {
    const mergedProps = {};

    for (let provider of providers) {
      let providerMergedProps = provider.merge(
        stateProps, dispatchProps, parentProps
      );

      invariant(
        isPlainObject(providerMergedProps),
        '`merge` must return an object. Instead received %s.',
        providerMergedProps
      );

      Object.assign(mergedProps, providerMergedProps);
    }

    return mergedProps;
  }

  const Provide = class extends Component {
    static displayName = getDisplayName();
    static contextTypes = { store: storeShape };
    static propTypes = { store: storeShape };
    static WrappedComponent = WrappedComponent;
    static addProvider = addProvider;

    shouldComponentUpdate(nextProps, nextState) {
      return !shallowEqual(this.state.props, nextState.props);
    }

    constructor(props, context) {
      super(props, context);
      this.version = version;
      this.store = props.store || context.store;

      invariant(this.store,
        `Could not find "store" in either the context or ` +
        `props of "${this.constructor.displayName}". ` +
        `Either wrap the root component in a <Provider>, ` +
        `or explicitly pass "store" as a prop to "${this.constructor.displayName}".`
      );

      this.stateProps = computeStateProps(this.store);
      this.dispatchProps = computeDispatchProps(this.store);
      this.state = { props: this.computeNextState() };
    }

    recomputeStateProps() {
      const nextStateProps = computeStateProps(this.store);
      if (shallowEqual(nextStateProps, this.stateProps)) {
        return false;
      }

      this.stateProps = nextStateProps;
      return true;
    }

    recomputeDispatchProps() {
      const nextDispatchProps = computeDispatchProps(this.store);
      if (shallowEqual(nextDispatchProps, this.dispatchProps)) {
        return false;
      }

      this.dispatchProps = nextDispatchProps;
      return true;
    }

    computeNextState(props = this.props) {
      return computeNextState(
        this.stateProps,
        this.dispatchProps,
        props
      );
    }

    recomputeState(props = this.props) {
      const nextState = this.computeNextState(props);
      if (!shallowEqual(nextState, this.state.props)) {
        this.setState({ props: nextState });
      }
    }

    isSubscribed() {
      return typeof this.unsubscribe === 'function';
    }

    trySubscribe() {
      if (shouldSubscribe && !this.unsubscribe) {
        this.unsubscribe = this.store.subscribe(::this.handleChange);
        this.handleChange();
      }
    }

    tryUnsubscribe() {
      if (this.unsubscribe) {
        this.unsubscribe();
        this.unsubscribe = null;
      }
    }

    componentDidMount() {
      this.trySubscribe();
    }

    componentWillReceiveProps(nextProps) {
      if (!shallowEqual(nextProps, this.props)) {
        this.recomputeState(nextProps);
      }
    }

    componentWillUnmount() {
      this.tryUnsubscribe();
    }

    handleChange() {
      if (this.recomputeStateProps()) {
        this.recomputeState();
      }
    }

    getWrappedInstance() {
      return this.refs.wrappedInstance;
    }

    render() {
      return (
        <WrappedComponent ref='wrappedInstance' {...this.state.props} />
      );
    }
  }

  if ((
    // Node-like CommonJS environments (Browserify, Webpack)
    typeof process !== 'undefined' &&
    typeof process.env !== 'undefined' &&
    process.env.NODE_ENV !== 'production'
   ) ||
    // React Native
    typeof __DEV__ !== 'undefined' &&
    __DEV__ //eslint-disable-line no-undef
  ) {
    Provide.prototype.componentWillUpdate = function componentWillUpdate () {
      if (this.version === version) {
        return;
      }

      // We are hot reloading!
      this.version = version;

      // Update the state and bindings.
      this.trySubscribe();
      this.recomputeStateProps();
      this.recomputeDispatchProps();
      this.recomputeState();
    };
  }

  return Provide;
}

provide рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдПрдХ рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк react-devtools рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдм рдХреБрдЫ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХреБрдЫ рдРрд╕рд╛ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ ( Branches ProvideBranches(theme,packageList,sources) рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ
2015-08-15-010648_1366x768_scrot

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп (рдЬрд┐рд╕реЗ рдЖрдк рдореВрд▓ connect рд╕рд╛рде рджреЗрдЦреЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ Branches Connect(Branches) рд╕рд╛рде рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ):
2015-08-14-220140_1366x768_scrot

рд╕реАрдорд╛рдУрдВ

рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рджреЛ рджрд┐рди рдкрд╣рд▓реЗ redux рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХреНрдпрд╛ (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рд╕реАрдорд╛рдПрдВ рдореМрдЬреВрдж рд╣реИрдВред рдореЗрд░реЗ рд╕рд┐рд░ рдХреЗ рдКрдкрд░ рд╕реЗ, рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рд╕реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪ рд╕рдХрддрд╛, рдФрд░ рдореЗрд░реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдХреЛрдИ рдФрд░ рдЕрдиреБрднрд╡реА рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВ рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдЖрдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ _truly_ "рдЧреВрдВрдЧрд╛" рдШрдЯрдХ рд╣реЛрдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкрд╕рдВрдж рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рднреА рдкреНрд░рджрд╛рддрд╛ рдХреЛ рдЙрдиреНрд╣реЗрдВ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЪрд┐рдВрддрд╛рдУрдВ рдХреЗ рдПрдХ рд╕рдЪреНрдЪреЗ рдЕрд▓рдЧрд╛рд╡ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рд╡рд┐рдирд┐рдореЗрдп рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреА рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдЧрд░ @gaearon рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ react-redux рдХреЗ рджрд╛рдпрд░реЗ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЗ рд╕рд╛рде рдПрдХ рдкреАрдЖрд░ рд╕рдмрдорд┐рдЯ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╢рд╛рдпрдж рдореИрдВ react-redux-providers рдмрдирд╛рдКрдВрдЧрд╛ рдФрд░ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░реВрдВрдЧрд╛, рдФрд░ рдлрд┐рд░ рдЕрдВрддрддрдГ рдХреБрдЫ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рддрд╛рдУрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, react-redux-provide-toggle рдЬреИрд╕реА рд╕рд╛рдордЧреНрд░реА) рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░реВрдВрдЧрд╛ред

рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдордзреНрдп-рд╕реНрддрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреБрди: рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг рд╕реЗ рдмрдЪ рд╕рдХрддреЗ рд╣реИрдВ?

рд╣рд╛рдВ

рдЕрдм рд╣рдордиреЗ рдЬреЛ рджрд┐рд╢рд╛ рд▓реА рд╣реИ, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдХреЗ рд▓рд┐рдП Immutable.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ (рдРрдк рд╕реНрдЯреЗрдЯ рдФрд░ UI рд╕реНрдЯреЗрдЯ рджреЛрдиреЛрдВ; рд╣рдо рдШрдЯрдХреЛрдВ рдореЗрдВ рдХреБрдЫ UI рд╕реНрдЯреЗрдЯ рд░рдЦрддреЗ рд╣реИрдВ), рдФрд░ рдлрд┐рд░ рдЕрдкрдиреЗ рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП PureRenderMixin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдХреНрдпрд╛ рдпрд╣ рдЯреЙрдк-рдбрд╛рдЙрди рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рджрдВрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛?

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореБрдЭреЗ рдЕрднреА рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рд╣реИ рдХрд┐ рдпрд╣ рдордзреНрдп-рд╕реНрддрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрд╕ рдкреНрд░рджрд░реНрд╢рди рджрдВрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдЙрдирдХреЗ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдЕрднреА рднреА рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЕрднреА рднреА рдмрд╣реБрдд рдЕрдзрд┐рдХ рдУрд╡рд░рд╣реЗрдб рдХреЛ рдЦрддреНрдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рд╕рд╛рде рдХреЛрдИ рдЕрдиреБрднрд╡?

@ danmaz74 рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдореЗрдВ perf рдореБрджреНрджреЛрдВ рдХреЛ рдорд╛рд░ рд░рд╣реЗ рд╣реИрдВ (redux рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рдорд╛рди рдШрд░ рдореЗрдВ рдмрдиреЗ lib)ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдмрд╣реБрдд рд╣реА "рдорд╣рдВрдЧреЗ" рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдРрдк рд╣реИред рд╕рд╛рде рд╣реА, рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдРрдк рдмрдбрд╝рд╛ рд╣реЛрддрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рд╢реАрд░реНрд╖ рд╕реНрддрд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХреЛ рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рдирд┐рд╣рд┐рдд рдирд┐рд░реНрднрд░рддрд╛ рдмрдирд╛рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓ рд╕рдХрддреА рд╣реИ рдФрд░ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдЕрдкрдиреЗ рдмрдЪреНрдЪреЛрдВ рдХреА рдбреЗрдЯрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓ рд╕рдХрддреА рд╣реИред

@eldh рдЕрджреНрдпрддрди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╕рдордп рд╣рдо рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВрдЧреЗ :)

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

рдПрдХ рдПрдХрд▓ рдХрдиреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╛рдЬреНрдп рдХреЛ рд╕рднреА рддрд░рд╣ рд╕реЗ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд╛рд▓ mapStateToProps рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреИрд╕реЗ рдХрд┐ 10 рдШрдЯрдХ рдЧрд╣рд░реЗ рдкрджрд╛рдиреБрдХреНрд░рдо ... рдореИрдВ рдереЛрдбрд╝рд╛ рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВ рдХрд┐ рдЗрд╕рдХреЗ рдкреАрдЫреЗ рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ рдпрд╛ рдХреНрдпрд╛ рдореИрдВ рдХреБрдЫ рдЧрд▓рдд рд╕рдордЭ рд░рд╣рд╛ рд╣реВрдВ ...

рдПрдХрд▓ рдХрдиреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд╛рд▓ mapStateToProps рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА

рдХреЛрдИ рднреА рдПрдХрд▓ рдХрдиреЗрдХреНрдЯ рдХреА рд╡рдХрд╛рд▓рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

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

"рдПрдХрд▓" рдХреЗрд╡рд▓ рдЫреЛрдЯреЗ рдРрдкреНрд╕ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рд╣рдо рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВред рдХреГрдкрдпрд╛ рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рд╕рдВрд╢реЛрдзрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред рдореИрдВ рдЕрдм рдЕрдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╡реНрдпрд╕реНрдд рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдХреГрдкрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рд╣рд▓рдЪрд▓ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рди рдХрд░реЗрдВ рдЬрдм рддрдХ рдХрд┐ рдХреЛрдИ рдкреАрдЖрд░ рдирд╣реАрдВ рдХрд░рддрд╛ред рддреБрдо рд╕реЗ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдЕрдВрдд рдореЗрдВ react-redux-provide рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛ рдЧрдпрд╛ред рдЗрд╕реЗ рдпрд╣рд╛рдВ рджреЗрдЦреЗрдВ ред рдореИрдВ рдЕрдЧрд▓реЗ рдХреБрдЫ рджрд┐рдиреЛрдВ/рд╕рдкреНрддрд╛рд╣реЛрдВ рдореЗрдВ рдХреБрдЫ рдЕрдиреНрдп рд╕рд╛рдордЧреНрд░реА рднреА рдЬрд╛рд░реА рдХрд░реВрдБрдЧрд╛ред

рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдореИрдВрдиреЗ рдЕрднреА рдПрдХ рдирдпрд╛ рд░реЗрдбрдХреНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╢реБрд░реВ рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ 'рд╕реНрдорд╛рд░реНрдЯ' рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ - рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╣реАрдВ рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдХреЛрдИ рдкреВрд░реНрдг рд▓рд╛рдн рд╣реИ рддреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬреАрдд рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрджрд┐ рдЖрдкрдиреЗ рдореБрдЦреНрдп рдРрдк рдпрд╛ рд░рд╛рдЙрдЯрд░ рддрдХ рд╕рднреА рдирд┐рдпрдВрддреНрд░рдг рдмрдмрд▓ рдХрд░ рджрд┐рдП рд╣реИрдВ, рддреЛ рдПрд╕рдЖрд░рдкреА рдХрд╛ рдкреВрд░реНрдг рдиреБрдХрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИ - рдЪреАрдЬреЛрдВ рдХреЛ рддреЛрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЗ рдРрдк рдХреЛ рдХрд┐рддрдирд╛ рдмрдбрд╝рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдореИрдВ рд╕рдВрдмрдВрдзрд┐рдд рддрддреНрд╡реЛрдВ рдХреЛ рдШрдЯрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ - рдпрд╛рдиреАред рдЗрд╕рдХреЗ рдореБрдЦреНрдп рдШрдЯрдХ рдЖрджрд┐ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдПрдХ рд░реЗрдбреНрдпреВрд╕рд░ рд▓рдЧрд╛рдПрдВред

рдЕрдВрддрддрдГ, рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рд░реЗрдбрдХреНрд╕/рдлреНрд▓рдХреНрд╕ рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рдирд┐рдд рдЕрд╡рд╕реНрдерд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд▓рд╛рдн рд╣реИ, рд▓реЗрдХрд┐рди рдорд╛рдирдХ рдПрдорд╡реА рд╕реЗ рдЗрд╕ рддрд░рд╣ рдХреА рдорд╛рдирд╕рд┐рдХ рдмрджрд▓рд╛рд╡-рдЬреЛ рдХреБрдЫ рднреА рдпреВрдЖрдИ рдРрдк рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЛ рд╕рд░рд▓ рдФрд░ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рднреА рд╕реБрд▓рдн рдмрдирд╛рддрд╛ рд╣реИ, рдЕрдВрддрддрдГ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рджреВрд░ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╣рдо рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗ рдХрд┐рд╕реА рдРрд╕реА рдЪреАрдЬрд╝ рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдБ рдЬреЛ mv* рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рджрд┐рдЦрддреА рд╣реЛред

рдпрд╣ #1285 рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рд╣рдо рдЕрдм рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдмрдирд╛рдиреЗ рдХреЛ рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ.
http://redux.js.org/docs/basics/UsageWithReact.html

рдЕрд░реЗ рдореИрдВрдиреЗ рдХреБрдЫ рд╕рд╛рдорд╛рдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рдпрд╣рд╛рдВ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред :)

https://medium.com/@timbur/react -automatic-redux-providers-and-replicators-c4e35a39f1

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ https://github.com/reactjs/redux/issues/419#issuecomment -183769392 #1353 рдХреЗ рд╕рд╛рде рднреА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред

@timbur рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ рд▓реЗрдЦ! рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЗрд╕ рдкреНрд░рд╢реНрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкрдиреЗ рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: https://github.com/reactjs/react-redux/issues/278

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

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

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

рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдЕрдХреНрд╕рд░ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╕реНрдорд╛рд░реНрдЯ рдШрдЯрдХреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдИрдбреА рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИред рдПрдХ рдЖрдИрдбреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдПрдХ рд╕рдВрдХреЗрдд рд╣реИ рдХрд┐ рдХреБрдЫ рдРрдк рдХреЗ рдбреЛрдореЗрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдЗрд╕рд▓рд┐рдП рдЬрд╣рд╛рдВ рд╕рдВрднрд╡ рд╣реЛ рдПрдХ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдЖрдИрдбреА рдХреА рд╕реВрдЪрд┐рдпрд╛рдВ рд▓реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рджреВрд╕рд░реЗ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рднреЗрдЬ рджреЗрдВ, рдЬреЛ рдЖрдИрдбреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдкрдиреА рдЗрдЪреНрдЫрд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдИрдбреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдЙрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдХрдВрдЯреЗрдирд░ рдХреЗ рднреАрддрд░ рдПрдХ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдиреАрдЪреЗ рдореИрдВрдиреЗ рдПрдХ рдХрдВрдЯреЗрдирд░ рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдРрдк рдХреЗ рдХрдиреЗрдХреНрдЯреЗрдб рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ (рдЬрдЯрд┐рд▓) рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛рдпрд╛ рд╣реИ рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШрдЯрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

// Provider component that renders some containers and some components and provides the store
class TodoAppProvider {
  constructor() {
    // setup store etc.
  }

  render() {
    return (
      <Provider store={this.store}> {/* Provider from 'react-redux' */}
        <AppLayoutComponent title="My Todos" footer={<TodoFooter />}>
          <TodoListsContainer />
        </AppLayoutComponent>
      </Provider>
    );
  }
);

// AppLayoutComponent
// Lots of nice css, other dumb components etc. no containers!
export default const AppLayoutComponent = ({ title, children, footer }) => (
  <header>
    {title}
  </header>
  <main>
    {children /* This variable can be a container or components but it's not hardcoded! */}
  </main>
  <footer>
    {footer}
  </footer>
);

// TodoFooter
// Another dumb component
export default const TodoFooter = () => (
  <footer>
    &copy; {Date.now() /* we are copyrighted to the millisecond */}
  </footer>
);

// TodoListsContainer
// Smart component that renders all the lists
class TodoListsContainer extends React.Component {
  render() {
    return () {
      <div>
        {todoLists.map(id => (
          {/* this container renders another container */ }
          <TodoListContainer key={id} todoListId={id} />
        ))}
      </div>
    }
  }
}

const mapStateToProps = state => ({
  todoLists: getTodoLists(state),
});

export default connect(mapStateToProps)(TodoListsContainer);

// TodoListContainer
// Gets the props and visibleTodo IDs for the list
class TodoListContainer {
  render() {
    const { id, title, visibleTodos } = this.props;
    return (
      <div>
        {/* Render a component but passes any connected data in as props / children */}
        <TodoListPanelComponent title={title}>
          {visibleTodos.map(id => (
            <TodoContainer todoId={id} />
          ))}
        </TodoListPanelComponent>
      </div>
    );
  }
}

const mapStateToProps = (state, { todoListId }) => ({
  ...getTodoList(state, todoListId), // A todo object (assume we need all the attributes)
  visibleTodos: getVisibleTodos(state, todoListId), // returns ids
});

export default connect(mapStateToProps)(TodoListContainer);


// TodoListPanelComponent
// render the panel to sit the todos in
// children should be todos
// No containers!
export default const TodoListPanelComponent = ({ title, children }) => (
  <div>
    <h3>{title}</h3>
    <div>
      {children}
    </div>
  </div>
);

// TodoContainer
// This just wraps the TodoComponent and passed the props
// No separate class or JSX required!
const mapStateToProps = (state, { todoId }) => ({
  ...getTodo(state, todoId),
});

const mapDispatchToProps = (dispatch, { todoListId }) => ({
  handleFilter: () => dispatch(hideTodo(id)), // Pass ALL smart stuff in
});

export default connect(mapStateToProps, mapDispatchToProps)(TodoComponent); // Passing in the component to connect

// TodoComponent
// Render the component nicely; again, as all of its connected stuff passed in
// The FilterLinkContainer is an example of a smell that will come back to bite you!
export default const TodoComponent = ({ content, isComplete, handleFilter }) => (
  <div>
    <div>
      {content}
    </div>
    <div>
      {isComplete ? 'тЬУ' : 'тЬЧ'}
    </div>
    <div>
      {/* Don't do this, can't re-use TodoComponent outside the app context! */}
      <FilterLinkContainer />

      {/* Instead do this (or similar), component can be reused! */}
      <Link onClick={handleFilter}>
        'Filter'
      </Link>
    </div>
  </div>
);

рддреЛ рдпрд╣рд╛рдВ рдХрдВрдЯреЗрдирд░ рдкрджрд╛рдиреБрдХреНрд░рдо TodoAppProvider > TodoListsContainer > TodoListContainer > TodoContainer ред рд╡реЗ рдкреНрд░рддреНрдпреЗрдХ рдПрдХ рджреВрд╕рд░реЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдХрднреА рднреА рдПрдХ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рдореЗрдВ рдХреЛрдИ рдХрдЪреНрдЪрд╛ рджреГрд╢реНрдп рдХреЛрдб рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рд░рд┐рдПрдХреНрдЯ рд░реИрдкрд┐рдВрдЧ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдордпрд┐рдХ div рдХреЗ рдЕрд▓рд╛рд╡рд╛)ред

рдЕрдВрддрдд:, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рд╢реБрд░реВ рдореЗрдВ рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рдкреЗрдбрд╝ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ рдЬреЛ рдЖрдкрдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдЙрдкрдпреЛрдЧреА рддрд░реАрдХреЗ рд╕реЗ рдореИрдк рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдЖрдкрдХрд╛ UI _will_ рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдИ рдпреВрдЖрдИ рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореИрдк рдХрд┐рдП рдЧрдП рд░рд╛рдЬреНрдп рдХрд╛ рдПрдХ рдкреЗрдбрд╝ рд╣реИред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдЙрди рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рдЕрдВрджрд░ рдкреНрд░рд╕реНрддреБрддрд┐рдХрд░рдг рдШрдЯрдХреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫрд┐рдбрд╝рдХрддреЗ рд╣реИрдВ (рдпрд╛рдиреА рдбреАрдУрдПрдо рдореЗрдВ)ред рдЬрд╛рд╣рд┐рд░ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдРрдк рдХреЛ рдЗрд╕ рдЯреВ-рдкрд╛рд╕ рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рдореЙрдбрд▓ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд░рдирд╛ рдЙрдкрдпреЛрдЧреА рд▓рдЧрд╛ред

рдХреНрдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ connect() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреНрд░рджрд░реНрд╢рди рджрдВрдб (рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╡рд╛рд╕реНрддреБ рдХрд╛рд░рдг) рд╣реИ? рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рдЙрдирдХреЗ рдХрдиреЗрдХреНрдЯ рдПрдВрдЯреНрд░реА рдкреЙрдЗрдВрдЯ рдХреЛ рд╕рд╛рд░рдгрд┐рдд рдХрд░рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░реЛрдк рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

// connectCommonProps.js (mergeProps not included for the sake of simplicity)

const _mapStateToProps = (state) => ({ [often used slices of state] });

const _mapDispatchToProps = (dispatch) => ({ [often used actions] });

const connectCommonProps = (mapStateToProps, mapDispatchToProps, component) => {
    // First connect
    const connectedComponent = connect(mapStateToProps, mapDispatchToProps)(component);

    // Second connect
    return connect(_mapStateToProps, _mapDispatchToProps)(connectedComponent);
};

export default connectMapAndFieldProps;
// Some component that needs the often used props
...
export default connectCommonProps(..., ..., Component);

рдореИрдВ рдпрд╣рд╛рдБ рдЖрд▓рд╕реА рд╣реЛ рд░рд╣рд╛ рд╣реВрдБ рдФрд░ mapStateToProps рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдФрд░ mapDispatchToProps рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдШреЛрд╖рдгрд╛ рдХреЛ рд╕рд░рд▓ рд░рдЦрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рдЧреАрд▓рд╛ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ connect рдХреЛ рдореЗрд░реЗ рд▓рд┐рдП рд╡рд╣ рдХрд╛рдо рдХрд░рдиреЗ рджреЗрдирд╛ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред

@timotgl : рдбреИрди рдЕрдм рд╕рдХреНрд░рд┐рдп рдЕрдиреБрд░рдХреНрд╖рдХ рдирд╣реАрдВ рд╣реИ - рдХреГрдкрдпрд╛ рдЙрд╕реЗ рд╕реАрдзреЗ рдкрд┐рдВрдЧ рди рдХрд░реЗрдВред

рдореИрдВ рдпрд╣ рдХрд╣рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛ рдХрд┐ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ Redux FAQ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдореЗрдВ рдХрдИ рдШрдЯрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдкрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХреБрдЫ рдЕрд▓рдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫ рд░рд╣реЗ рд╣реИрдВ - рдЬрд╛рдирдмреВрдЭрдХрд░ рдПрдХ рд╣реА рдШрдЯрдХ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрдИ рдХрдиреЗрдХреНрд╢рди рд▓рдкреЗрдЯ рд░рд╣реЗ рд╣реИрдВ? рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддрд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХрднреА рдХрд┐рд╕реА рдХреЛ рдРрд╕рд╛ рдХрд░рддреЗ рджреЗрдЦрд╛ рд╣реИ, рдФрд░ рдореИрдВрдиреЗ Redux рдХреЛрдб рдХрд╛ _lot_ рджреЗрдЦрд╛ рд╣реИред

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

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

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

рдореИрдВрдиреЗ рдПрдЪрдУрд╕реА рдХреЗ рдЦрд┐рд▓рд╛рдл рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдУрдУрдкреА/рд╡рд┐рд░рд╛рд╕рдд рдкреНрд░рддрд┐рдорд╛рди рдХреЛ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдШрдЯрдХ рдХреЛ рдХреБрдЫ рдФрд░ рдкреНрд░реЛрдк рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ, рдЗрд╕рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрдиреНрдпрдерд╛ рдЫреВрдЯрд╛ рд╣реБрдЖ рд╣реИред

mapStateToProps рдореЗрдВ рд╡рд╛рдпрд░рд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИред рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛ рд▓реЗрдХрд┐рди рдлрд┐рд░ рдореЗрд░реЗ рдкрд╛рд╕ рдХрдо рд╕реЗ рдХрдо 2 рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИрдВ - рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реАрдзреЗ рдЖрдЧреЗ рд▓рдЧрддрд╛ рд╣реИред

рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ "рджреЛ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ" рд╕реЗ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИред

рдореИрдВ рдЬреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ:

import {selectCommonProps} from "app/commonSelectors";

import {selectA, selectB} from "./specificSelectors";

const mapState = (state) => {
    const propA = selectA(state);
    const propB = selectB(state);
    const commonProps = selectCommonProps(state);

    return {a, b, ...commonProps};
}

@markerikson рджреЛ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБрдУрдВ рд╕реЗ рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ рдХрд┐ рдЖрдкрдХреЛ mapDispatchToProps , рдФрд░ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ mergeProps ред

рдЖрдкрдХреЛ рд▓рдЧрднрдЧ рдХрднреА рднреА mergeProps рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП - рдпрд╣ рдЕрдВрддрд┐рдо рдЙрдкрд╛рдп рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдЪ рдХреЗ рд░реВрдк рдореЗрдВ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдЖрдо рддреМрд░ рдкрд░ рдпрд╣ рднреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ mapDispatch рдлрд╝рдВрдХреНрд╢рди рди рд▓рд┐рдЦреЗрдВ, рдФрд░ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп "рдСрдмреНрдЬреЗрдХреНрдЯ рд╢реЙрд░реНрдЯрд╣реИрдВрдб" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

import {addTodo, toggleTodo} from "./todoActions";

class TodoList extends Component {}

const actions = {addTodo, toggleTodo};
export default connect(mapState, actions)(TodoList);

рдЖрдкрдХреЗ рдкрд╛рд╕ рдЖрд╕рд╛рдиреА рд╕реЗ рдХреБрдЫ index.js рдлрд╝рд╛рдЗрд▓ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬреЛ рдЖрдкрдХреЗ рд╕рднреА "рдХреЙрдорди" рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рдПрдХреНрд╕рдкреЛрд░реНрдЯ рдХрд░рддреА рд╣реИ, рдФрд░ рдХреБрдЫ рдРрд╕рд╛ рдХрд░реЗрдВ:

import * as commonActions from "app/common/commonActions";
import {specificAction1, specificAction2} from "./actions";

const actionCreators = {specificAction1, specificAction2, ...commonActions};

export default connect(null, actionCreators)(MyComponent);

рдЖрдкрдХреЛ рд▓рдЧрднрдЧ рдХрднреА рднреА mergeProps рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП - рдпрд╣ рдЕрдВрддрд┐рдо рдЙрдкрд╛рдп рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдЪ рдХреЗ рд░реВрдк рдореЗрдВ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рд╣реИрд▓реЛ @markerikson , рдореИрдВ рдмрд╕ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЙрддреНрд╕реБрдХ рд╣реВрдВ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рдорд░реНрдЬрдкреНрд░реЙрдкреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдХреНрдпреЛрдВ рдмрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП? рдореБрдЭреЗ mapStateToProps рд╕реЗ рдкреНрд░реЙрдкреНрд╕ рдХреЛ "рдЫрд┐рдкрд╛рдирд╛" рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд▓рдЧрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рдореБрдЭреЗ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ mapDispatchToProps рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдШрдЯрдХ рдореЗрдВ рдирд╣реАрдВред рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдмреБрд░реА рдмрд╛рдд рд╣реИ?

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

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

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

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

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

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

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