Redux: рдХрд┐рд╕реА рдкреНрд░рджрд╛рддрд╛ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рджреЗ рд╕рдХрддреЗ рдпрд╛ рдПрдВрдЬрд╛рдЗрдо рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ

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

рдореИрдВ <Provider> рдФрд░ connect . рдореЗрдВ рд▓рд┐рдкрдЯреЗ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХрд╛ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛

// test
let component = shallow(<Provider store={store}><ContainerComponent /></Provider>);
component.find('#abc'); // returns null

let component = shallow(<Provider store={store}><div id="abc"></div></Provider>);
component.find('#abc'); // returns the div node

// ContainerComponent
const Component = ({...}) => (<div id="abc"></div>);
export default connect(..., ...)(Component);

рдореИрдВрдиреЗ рдЕрдиреБрд╕рд░рдг рдХрд┐рдпрд╛: https://github.com/reactjs/redux/issues/1481 рдЙрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдВ рдкрд░реАрдХреНрд╖рдг рдПрдВрдЬрд╛рдЗрдо рдХреЗ рд╕рд╛рде рд▓рд┐рдЦреЗ рдЧрдП рдереЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрднреА рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдореБрдЭреЗ рд╕реНрдорд╛рд░реНрдЯ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдирд╣реАрдВ?

@fshowalter рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

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

рднрд▓реЗ рд╣реА рдпрд╣ рд╕реАрдзреЗ Redux рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХрдВрдЯреЗрдирд░ рдкрд░ shallow() рдкрд░ рдХреЙрд▓ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ред рдпрд╣ рдЖрдВрддрд░рд┐рдХ рдШрдЯрдХ рдХреЛ рд╕реНрдЯреЛрд░ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:

import React from 'react';
import {expect} from 'chai';
import {shallow} from 'enzyme';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import events from 'events';

const mockStore = configureMockStore([ thunk ]);
const storeStateMock = {
  myReducer:{
    someState: 'ABC'
  }
};

let store;
let component;
describe('tests for MyContainerComponent', () => {
  beforeEach(() => {
    store = mockStore(storeStateMock);
    component = shallow(<MyContainerComponent store={store} />).shallow();
  });

  it('renders container', () => {
    expect(component.find('div.somediv')).to.have.length.of(1);
  });
  ...
});

рдЙрдореНрдореАрдж рд╣реИ рдХреА рдпрд╣ рдорджрдж рдХрд░реЗрдЧрд╛

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

рди рддреЛ connect() рдФрд░ рди рд╣реА Provider рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИрдВред рдРрд╕реЗ рдореБрджреНрджреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЙрдиреНрд╣реЗрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЙрдкрдпреБрдХреНрдд рднрдВрдбрд╛рд░ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: https://github.com/reactjs/react-reduxред

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

рдпрд╣рд╛рдБ рджреЛ рд╡рд┐рдЪрд╛рд░:

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ connect() рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд░реИрдкрд░ рдШрдЯрдХ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ props.store рдХреА рддрд▓рд╛рд╢ рдХрд░рддрд╛ рд╣реИ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╡рд╣ context.store рдХреА рддрд▓рд╛рд╢ рдХрд░реЗ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ , рдЖрдкрдХреЛ рдкреНрд░рджрд╛рддрд╛ рдпрд╛ рд╕рдВрджрд░реНрдн рдпрд╛ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ <ConnectedComponent store={myTestStore} /> рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

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

@gaearon рдЖрдк рд╕рд╣реА рдХрд╣ рд░рд╣реЗ рд╣реИрдВ, рдХреНрд╖рдорд╛ рдХрд░реЗрдВред рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдЗрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдпрд╛ рдПрдВрдЬрд╛рдЗрдо рд░реЗрдкреЛ рдореЗрдВ рдмрдврд╝рд╛рдирд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред

@markerikson рд╕реНрдорд╛рд░реНрдЯ рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг mapToDispatchProps рдХреЗ рд▓рд┐рдП рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рд▓рд┐рдкрдЯреЗ рдШрдЯрдХ рджреНрд╡рд╛рд░рд╛ рд╕рд╣реА рдкреНрд░реЗрд╖рдХ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдмрд╕ рд╕реНрдЯреЛрд░ рдХреЛ ConnectedComponent рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдореИрдВ рд░рд╛рдЬреНрдп рдореИрдкрд┐рдВрдЧ рдпрд╛ рдкреНрд░реЗрд╖рдг рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░реВрдБрдЧрд╛ред

рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рд╕реЛрдЪреВрдВрдЧрд╛ рдФрд░ рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рд╕рдВрдмрдВрдзрд┐рдд рд░реЗрдкреЛ рдореЗрдВ рдПрдХ рдореБрджреНрджрд╛ рдЙрдард╛рдКрдВрдЧрд╛ред рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

@ рдореЛрд░реНрдбреНрд░рд╛ : рдЬрдм рдЖрдк рдХрд╣рддреЗ рд╣реИрдВ "рд╕рд╣реА рдкреНрд░реЗрд╖рдХ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛", рдХреНрдпрд╛ рдЖрдкрдХрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ "рд╕рд╣реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдирд┐рд░реНрдорд╛рддрд╛" рд╣реИ?

рдЖрдк рдРрд╕рд╛ рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╢рд╛рдпрдж рдмрдВрдж рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП):

let actionSpy = sinon.spy();

let wrapper = shallow(<PlainComponent someActionProp={actionSpy} />);
wrapper.find(".triggerActionButton").simulate("click");
expect(actionSpy.calledOnce).to.be.true;
expect(actionSpy.calledWith({type : ACTION_I_WAS_EXPECTING)).to.be.true;

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

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

@markerikson рдореИрдВ рд╡рд╣ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдЬреЛ рдЖрдк рд╕реБрдЭрд╛ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ PlainComponent рдХреЛ рдХреНрд░рд┐рдпрд╛рдУрдВ рдпрд╛ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХрд░рдиреЗ рдХрд╛ рдпрд╣ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рджреЗрдЦреЗрдВ:
https://github.com/mordra/cotwmtor/blob/master/client/charCreation/charCreation.jsx
рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдореЗрд░реЗ mapDispatchToProps рдореЗрдВ рд╕рднреА рддрд░реНрдХ рд╣реИрдВ:

const mapDispatchToProps = (dispatch) => {
  return {
    onCompleted      : (player) => {
      Meteor.call('newGame', player, function (data) {
        console.log('new game return: ' + data);
      });
      dispatch(routeActions.push('/game'));
      dispatch({type: "INIT_GAME", map: generateAreas(), buildings: generateBuildings(dispatch)});
    },
    onCancelled      : () => dispatch(routeActions.push('/')),
    onChangeName     : input => dispatch(actions.changeName(input)),
    onChangeGender   : gender => dispatch(actions.setGender(gender)),
    onSetDifficulty  : lvl => dispatch(actions.setDifficulty(lvl)),
    onChangeAttribute: (attr, val) => dispatch(actions.setAttribute(attr, val))
  }
};

рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдореИрдВ рдкреНрд▓реЗрдирдХрдВрдкреЛрдиреЗрдВрдЯ рдореЗрдВ рдкрд╛рд░рд┐рдд рдкреНрд░реЙрдкреНрд╕ рдкрд░ рдЬрд╛рд╕реВрд╕реА рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░ рдкрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╕рд╣реА рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд╣рд▓рд╛рддреА рд╣реИрдВ, рдмрд▓реНрдХрд┐, рдХреЗрд╡рд▓ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХреЛ рджрд┐рдП рдЧрдП рдкреИрд░рд╛рдореАрдЯрд░ рд╕рд╣реА рд╣реИрдВред
рдлрд┐рд░ рдореБрдЭреЗ рдЕрд▓рдЧ рд╕реЗ connect рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЖрд╣ред рдЗрд╕рд╕реЗ рдореБрдЭреЗ рдФрд░ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред

рддреЛ рдЗрд╕ рдЪреЗрддрд╛рд╡рдиреА рдХреЗ рд╕рд╛рде рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рдХрд╛ рдмрд╣реБрдд рдХрдо рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрднрд╡ рд╣реИ, рдХреБрдЫ рд╡рд┐рдЪрд╛рд░:

  • рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХреНрд╢рди рдирд┐рд░реНрдорд╛рддрд╛ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк dispatch рддрдХ рдкрд╣реБрдВрдЪ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрд╣ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдмрд╣реБрдд рдЖрд╕рд╛рдиреА рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИред рдЖрдк рд╢рд╛рдпрдж рдЙрдирдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рднреА рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдЙрдиреНрд╣реЗрдВ mapDispatch рдХреЗ рдмрд╛рд╣рд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
  • рд╡реЗ рд╕рднреА рд░реЗрдбрдХреНрд╕-рдердВрдХ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫреЗ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ, рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ dispatch рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
  • рдЖрдкрдХрд╛ PlainComponent _does_ "рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпрд╛рдВ" рдпрд╛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдХреЙрд▓рдмреИрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдкрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдХрд╣реАрдВ рдЖрдкрдХреЗ рдШрдЯрдХ рдореЗрдВ рдЖрдк this.props.onSetDifficulty("HARD") рдпрд╛ рдРрд╕рд╛ рдХреБрдЫ рдЪрд▓рд╛ рд░рд╣реЗ рд╣реИрдВред рдЬрдм рдореИрдВрдиреЗ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╕реВрд╕реЛрдВ рдореЗрдВ рдЬрд╛рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛, рддреЛ рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬ рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗ рд░рд╣рд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЖрдк onSetDifficulty рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрд╛рд╕реВрд╕ рдореЗрдВ рдкрд╛рд╕ рд╣реБрдП рд╣реИрдВ, рддреЛ рдЖрдк рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЗ рдШрдЯрдХ рдиреЗ рдЗрд╕реЗ рдмреБрд▓рд╛рдпрд╛, рдФрд░ рдХрдард┐рдирд╛рдИ рд╕реНрддрд░ рдХреЗ рд▓рд┐рдП рд╕реНрд╡реАрдХрд╛рд░реНрдп рдореВрд▓реНрдп рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ред

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

рд╕рд╛рде рд╣реА, рдШрдЯрдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ: рдЕрдВрддрддрдГ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ {action: CHANGE_NAME, name : "Fred"} рднреЗрдЬрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрд╣ рдХреЗрд╡рд▓ рдЗрддрдирд╛ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ this.props.onChangeName("Fred") рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ _that_ рд╡рд╣ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП - рдХрд┐ рдЗрд╕реЗ рдкреНрд░реЛрдк рдХреЙрд▓рдмреИрдХ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

@mordra рдЖрдкрдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ mapDispatchToProps рдирд┐рд░реНрдпрд╛рдд рдХрд░реВрдВрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░реВрдВрдЧрд╛ред рдЖрдк рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рд╕рднреА рд╕рд╣реА рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рд╕реНрдкреИрдЪ рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрд╛рд╕реВрд╕ рдкрд╛рд╕ рдХрд░реЗрдВред

рдЙрд╕ рдиреЗ рдХрд╣рд╛, рдореИрдВ mapDispatchToProps рдХреЛ mapActionCreatorsToProps рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реВрдВ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЧрдард┐рдд рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХреЛ рдореИрдк рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдореЗрд░реЗ рд╕рднреА рдкреНрд░реЙрдкреНрд╕ рдХреЛ рдЖрдпрд╛рдд рдЯрд╛рдЗрдкреЛ рд╕реЗ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЕрдВрдд рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп (рдЙрдерд▓реЗ рдирд╣реАрдВ) рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдпрд╛ рддреЛ jsdom рдпрд╛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЖрдк рдХрд┐рд╕реА рднреА рд╕реНрддрд░ рдХреЛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдЗрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдпрд╛ рдПрдВрдЬрд╛рдЗрдо рд░реЗрдкреЛ рдореЗрдВ рдмрдврд╝рд╛рдирд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ

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

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

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

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

@gaearon : рддреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдЧрд░ рдореИрдВ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ:

let wrapper = shallow(<A><B /></A>);

рдмреА рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╛ рдирд╣реАрдВ? рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореВрд▓ рдкреНрд░рд╢реНрди рдпрд╣реА рдерд╛ - рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ рдХреЗ рдЖрд╕рдкрд╛рд╕ <Provider> рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рдерд╛ред

рднрд▓реЗ рд╣реА рдпрд╣ рд╕реАрдзреЗ Redux рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХрдВрдЯреЗрдирд░ рдкрд░ shallow() рдкрд░ рдХреЙрд▓ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ред рдпрд╣ рдЖрдВрддрд░рд┐рдХ рдШрдЯрдХ рдХреЛ рд╕реНрдЯреЛрд░ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:

import React from 'react';
import {expect} from 'chai';
import {shallow} from 'enzyme';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import events from 'events';

const mockStore = configureMockStore([ thunk ]);
const storeStateMock = {
  myReducer:{
    someState: 'ABC'
  }
};

let store;
let component;
describe('tests for MyContainerComponent', () => {
  beforeEach(() => {
    store = mockStore(storeStateMock);
    component = shallow(<MyContainerComponent store={store} />).shallow();
  });

  it('renders container', () => {
    expect(component.find('div.somediv')).to.have.length.of(1);
  });
  ...
});

рдЙрдореНрдореАрдж рд╣реИ рдХреА рдпрд╣ рдорджрдж рдХрд░реЗрдЧрд╛

рдХреНрдпрд╛ рд╣рдореЗрдВ рд╢рд╛рдпрдж рдПрдХ рдХрд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд▓рдн рддрд░реАрдХрд╛ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдП?

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЗрд╕рд▓рд┐рдП рд╣рдо рдХрдиреЗрдХреНрдЯ рдХреЛ рдПрдВрдЬрд╛рдЗрдо рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ component = shallowWithConnect()

@ ev1stensberg рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдХреНрдпрд╛ рд╣рдордиреЗ рддрдп рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣реА рддрд░реАрдХрд╛ рд╣реИ рдФрд░/рдпрд╛ рдЗрд╕ рдкрд░ рдХрд╛рдо рд╢реБрд░реВ рд╣реЛ рдЧрдпрд╛ рд╣реИ? рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдореБрдЭреЗ рдпреЛрдЧрджрд╛рди рджреЗрдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред

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

// test
let component = shallow(<Provider store={store}><ContainerComponent /></Provider>);
component.find('#abc'); // returns null

let component = shallow(<Provider store={store}><div id="abc"></div></Provider>);
component.find('#abc'); // returns the div node

// ContainerComponent
export const Component = ({...}) => (<div id="abc"></div>); // I EXPORT THIS, TOO, JUST FOR TESTING
export default connect(..., ...)(Component);

рддреЛ рдмрд╕ рдХрд░реЛ

const component = shallow(<Component {...props} />)
// test component

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

рдЦреИрд░, рдпрд╣рд╛рдБ рдзреНрдпрд╛рди рджреЗрдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдмрд╛рдд рд╣реИ рдХрд╛ рджрд░реНрд╢рди :

  1. рд╕реНрдЯреЛрд░ рд╕реЗ рдП . рддрдХ рд░рд╛рдЬреНрдп рдХрд╛ рд╕рдВрдЪрд╛рд░ рдХрд░реЗрдВ
  2. рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░реЗрд╖рдг рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд░рд╛рдЬреНрдп рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВ рдЖрдпреЛрдЬрдиред

рдЕрдЧрд░ рдореИрдВ рдареАрдХ рд╣реВрдВ рддреЛ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ 2 рдЪреАрдЬреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

  1. рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдШрдЯрдХ рд░рд╛рдЬреНрдп рд╕реЗ рдЙрддреНрдкрдиреНрди рд╕рд╣реА рдкреНрд░реЙрдкреНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реИ (рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ)?
  2. рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдШрдЯрдХ рд╕рд╣реА рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпрд╛рдВ рднреЗрдЬ рд░рд╣рд╛ рд╣реИ?

рддреЛ рдпрд╣ рдореЗрд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ

import React from 'react';
import { shallow } from 'enzyme';
import { fromJS } from 'immutable';
import { createStore } from 'redux';
// this is the <Map /> container
import Map from '../index';
// this is an action handled by a reducer
import { mSetRegion } from '../reducer';
// this is an action handled by a saga
import { sNewChan } from '../sagas';
// this is the component wrapped by the <Map /> container
import MapComponent from '../../../components/Map';

const region = {
  latitude: 20.1449858,
  longitude: -16.8884463,
  latitudeDelta: 0.0222,
  longitudeDelta: 0.0321,
};
const otherRegion = {
  latitude: 21.1449858,
  longitude: -12.8884463,
  latitudeDelta: 1.0222,
  longitudeDelta: 2.0321,
};
const coordinate = {
  latitude: 31.788,
  longitude: -102.43,
};
const marker1 = {
  coordinate,
};
const markers = [marker1];
const mapState = fromJS({
  region,
  markers,
});
const initialState = {
  map: mapState,
};
// we are not testing the reducer, so it's ok to have a do-nothing reducer
const reducer = state => state;
// just a mock
const dispatch = jest.fn();
// this is how i mock the dispatch method
const store = {
  ...createStore(reducer, initialState),
  dispatch,
};
const wrapper = shallow(
  <Map store={store} />,
);
const component = wrapper.find(MapComponent);

describe('<Map />', () => {
  it('should render', () => {
    expect(wrapper).toBeTruthy();
  });

  it('should pass the region as prop', () => {
    expect(component.props().region).toEqual(region);
  });

  it('should pass the markers as prop', () => {
    expect(component.props().markers).toEqual(markers);
  });
  // a signal is an action wich will be handled by a saga
  it('should dispatch an newChan signal', () => {
    component.simulate('longPress', { nativeEvent: { coordinate } });
    expect(dispatch.mock.calls.length).toBe(1);
    expect(dispatch.mock.calls[0][0]).toEqual(sNewChan(coordinate));
  });
  // a message is an action wich will be handled by a reducer
  it('should dispatch a setRegion message', () => {
    component.simulate('regionChange', otherRegion);
    expect(dispatch.mock.calls.length).toBe(2);
    expect(dispatch.mock.calls[1][0]).toEqual(mSetRegion(otherRegion));
  });
});

@markerikson рд╕реЗ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рдерд╛:

рдЖрдк рдЕрдкрдиреЗ mapStateToProps рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдк рдХрдиреЗрдХреНрдЯреЗрдб рдХрдВрдЯреЗрдирд░ рдХреЛ ES6 рдирд┐рд░реНрдпрд╛рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЖрдкрдХреЗ рдкрд╛рд╕ рдирд┐рдЬреА mapStateToProps рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реЛрдЧреАред рдХреНрдпрд╛ рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рдереЗ рдпрд╛ рдЖрдк рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ?

@mordrax

рдЖрдк рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рд╕рднреА рд╕рд╣реА рд╣реИрдВ

рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ mapStateToProps рдХрд╛ рдкрд░реНрджрд╛рдлрд╛рд╢ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХрд╣реЗрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдХрдВрдЯреЗрдирд░ рдХреЙрдореНрдкреЛрдиреЗрдВрдЯ рдХреЛ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдирдХрд▓реА рд╕реНрдЯреЛрд░ рднреЗрдЬрдирд╛ рдФрд░ рд░рд╛рдЬреНрдп рдкреНрд░реЛрдк рдореЗрдВ рднреЗрдЬрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рддреЛ рдЖрдкрдХрд╛ mapStateToProps рдЙрд╕ рд░рд╛рдЬреНрдп рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдПрдХ рдкреНрд░реЛрдк рдкрд░ рдореИрдк рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЖрдк рдЙрд╕ рдмрд┐рдВрджреБ рд╕реЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдХрдиреЗрдХреНрдЯ рдореИрдкрд╕реНрдЯреЗрдЯрдЯреЙрдкрдкреНрд░реЙрдкреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдкреНрд░реЙрдкреНрд╕ рдХреЛ рдорд░реНрдЬ рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реАрдо рдХрд╣рд╛рдВ рд╣реИ рдФрд░ рдЙрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛/рдкреНрд░рд╡рд╛рд╣ рдХреЗ рджреМрд░рд╛рди рдХреЛрдб рдореЗрдВ рд╕реАрдо рдХреМрди рд╕рд╛ рдмрд┐рдВрджреБ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рдирд▓ рдХрдВрдкреЛрдиреЗрдВрдЯ рдкрд░ рд╕реЗрдЯ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдкреНрд░реЙрдкреНрд╕ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @ guatedude2 рдХреА рддрд░рд╣ рдбрдмрд▓ рдЙрдерд▓реЗрдкрди рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕реАрдо рдХреЗ рдореИрдк рдХрд┐рдП рдЧрдП рдкреНрд░реЙрдкреНрд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ ...

рдЕрдкрдиреЗ рдЙрдерд▓реЗ.рдЙрдерд▓реЗ рдкрд░ рднреАред рддреЛ рдХрдиреЗрдХреНрдЯ () рдШрдЯрдХ рдХреНрдпрд╛ рд╡рд╛рдкрд╕ рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдПрдХ рд░реИрдкрд░ рд╕рд╣реА? рдФрд░ рд╡рд╣ рдЖрд╡рд░рдг рдЬреЛ рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг рдШрдЯрдХ рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ?

@granmoe рдХреНрдпрд╛ рдЖрдк рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╕рдордЭрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ:

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

рдореИрдВ _what_ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ @tugorez рдХреЗ рд╕рд╛рде рднреА рд╣реВрдВ рдФрд░ рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдХреНрдпреЛрдВред

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

рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдкреНрд░реЙрдкреНрд╕ рдпрд╛ рд╕реНрдЯреЗрдЯ рдкрд╛рд╕ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рдЖрдк рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рджреЛ рдЪреАрдЬреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛:

1) рдХреНрдпрд╛ рдХрдВрдЯреЗрдирд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдиреЗ рдкреНрд░реЙрдкреНрд╕ рдХреЛ рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рдирд▓ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд╡рд╛рдпрд░ рдХрд┐рдпрд╛ рдФрд░ рдЕрдЧрд░ рдРрд╕рд╛ рдХрд┐рдпрд╛, рддреЛ рдХреНрдпрд╛ рдХреЛрдИ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдерд┐рддрд┐ рд╣реИ, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рдирд▓ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЛ рдПрдХ рдмрд╛рд░ рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рдирд▓ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЗ рдкреНрд░реЙрдкреНрд╕ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдЙрд╕ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдЯреЗрдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд░реЗрдВрдбрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХреМрди рдЬрд╛рдирддрд╛ рд╣реИ, рд╢рд╛рдпрдж рдХреБрдЫ рдЧреВрдВрдЧрд╛ рдбреЗрд╡рд▓рдкрд░ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдФрд░ mapStateToProps рдореЗрдВ рдФрд░ рдХреЛрдб рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЖрдк рд╣рдореЗрд╢рд╛ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдХрд┐ рдпрд╣ рдЪреАрдЬреЛрдВ рдХреЛ рдареАрдХ рд╕реЗ рдореИрдк рдХрд░реЗрдЧрд╛, рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХрдВрдЯреЗрдирд░ рддрд░реНрдХ рдХрд╛ рдмрд┐рдВрджреБ рд╣реИред рдЬрдмрдХрд┐ mapStateToProps рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ, рдЬреЛ рдлрд┐рд░ рд╕реЗ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдбреЗрд╡рд▓рдкрд░ рд╕рд╛рде рдЖрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ рдПрдХ рдХрдерди рдХрд╛ рд╡рд┐рдЬреНрдЮрд╛рдкрди рдХрд░рддреЗ рд╣реИрдВ ... рдареАрдХ рд╣реИ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ рдЬреЛ рдЪреАрдЬреЛрдВ рдХреЛ рдЧрдбрд╝рдмрдбрд╝ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

2) рдкреНрд░реЗрд╖рдг рд╣реИрдВрдбрд▓рд░ рддрд░реНрдХ (рд╡реНрдпрд╡рд╣рд╛рд░) рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

@dschinkel :

Redux рд╕реЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрднреНрдпрд╛рд╕ рд╣реИ export default connect()(MyComponent) , рдФрд░ рдПрдХ рдирд╛рдорд┐рдд рдирд┐рд░реНрдпрд╛рдд рдХреЗ рд░реВрдк рдореЗрдВ export MyComponent рднреАред рдЗрд╕реА рддрд░рд╣, рдХреНрдпреЛрдВрдХрд┐ mapState рд╕рд┐рд░реНрдл рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЖрдк export const mapState = () => {} рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдЖрдпрд╛рдд рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

"рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ" рдмрдирд╛рдо "рдкреНрд░рд╕реНрддреБрддрд┐рдХрд░рдг рдШрдЯрдХ" рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП: рдпрд╣рд╛рдВ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдХрдВрдЯреЗрдирд░ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд┐рдд рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЬрд╣рд╛рдВ "рдХрдВрдЯреЗрдирд░" === "рдЖрдЙрдЯрдкреБрдЯ connect ". рд░рд┐рдПрдХреНрдЯ-рд░реЗрдбрдХреНрд╕ рдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдкреВрд░реНрдг рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рд╣реИ рдХрд┐ рдЙрд╕реЗ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрд╕ рдкреНрд░рдпрд╛рд╕ рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИред рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕реНрдЯреЛрд░ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ, mapState рдФрд░ mapDispatch рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдФрд░ рд░реИрдк рдХрд┐рдП рдЧрдП рдШрдЯрдХ рдХреЛ рдкреНрд░реЙрдкреНрд╕ рдкрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдВрдЪрд╛рд▓рди рдХрд░рддрд╛ рд╣реИред

рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЙрдкрднреЛрдХреНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ _you_ рдХреА рд░реБрдЪрд┐ рдЗрд╕ рдмрд╛рдд рдореЗрдВ рд╣реЛрдЧреА рдХрд┐ _your_ рдШрдЯрдХ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЛ connect рд░реИрдкрд░, рдПрдХ рдкрд░реАрдХреНрд╖рдг, рдпрд╛ рдХреБрдЫ рдФрд░ рд╕реЗ рд╕рд╣рд╛рд░рд╛ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ - рдпрд╣ рд╕рд┐рд░реНрдл рдЙрд╕ рдШрдЯрдХ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реЛрдк рдХреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реЗрдЯ рдХреЛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

(рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдлрдбрдмреНрд▓реНрдпреВрдЖрдИрдбрдмреНрд▓реНрдпреВ, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реИ рдХрд┐ рдЖрдк рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╣реИрдВ рдФрд░ рдореИрдВ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЪреАрдЬреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдкрд╛рдЧрд▓ рд╣реЛ рд░рд╣реЗ рд╣реИрдВ :) рдпрджрд┐ рдЖрдк mapState рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд┐рдд рд╣реИрдВ рдЧрд▓рддреА рд╕реЗ рдЯреВрдЯ рдЧрдпрд╛, рдлрд┐рд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВ рдФрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВред)

рдЕрдм, рдпрджрд┐ рдЖрдкрдХрд╛ рд▓рдкреЗрдЯрд╛ рд╣реБрдЖ рдШрдЯрдХ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдЕрдиреНрдп рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрджрд┐ рдЖрдк рдЙрдерд▓реЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рдмрдЬрд╛рдп рдкреВрд░реНрдг рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ const wrapper = mount(<Provider store={testStore}><MyConnectedComponent /></Provider> рдХрд░рдХреЗ рдЪреАрдЬреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди, рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдЖрдк рдЕрдкрдиреЗ mapState рдлрд╝рдВрдХреНрд╢рди рдФрд░ "рд╕рд╛рджреЗ" рдШрдЯрдХ рдХрд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЗрд╡рд▓ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрдЯреЗрдб рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ mapState рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рд╕рд╛рджреЗ рдШрдЯрдХ рдХреЛ рджрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП, рдЖрдк connect рдХреЗ рд▓рдШреБ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдбреИрди рдиреЗ рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ: https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e ред

рд╣рд╛рдБ, рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк mapStateToProps рдФрд░ dispatchStateToProps рдирд┐рд░реНрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ред рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдХрд┐ рдХрдиреЗрдХреНрдЯ() (рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕рд╣рдпреЛрдЧреА) рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд╣реАрдВред рддреЛ рдпрд╣ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛ рд╣реЛрдЧрд╛, рдЙрди рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ:

рдЙрджрд╛рд╣рд░рдг-рдХрдВрдЯреЗрдирд░-spec.js

describe('testing mapPropsToState directly', () => {
    it.only('returns expected state', () => {
        const state = {firstName: 'Dave'};
        const output = mapStateToProps(state);

        expect(output.firstName).to.equal('Dave');
    });
});

рдкрд╛рддреНрд░

import React from 'react';
import { connect } from 'react-redux'
import Example from './Example';

export const mapStateToProps = (state) => ({
    firstName: state.firstName
})

export default connect(mapStateToProps)(Example);

рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг

import React, { Component } from 'react';

export default class Example extends Component {
    render(){
        return (
            <div className='example'>
                {this.props.firstName}
            </div>
        )
    }
}

рдлрд┐рд░ рдлрд┐рд░, рдЖрдк _sallow_ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХреБрдЫ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрднреА рднреА рдмрд╛рд▓ рдШрдЯрдХ рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

рдЙрджрд╛рд╣рд░рдг-рдХрдВрдЯреЗрдирд░-spec.js

it('persists firstName to presentation component', () => {
        var state = {firstName: "Dave"};
        const container = mount(<ExampleContainer store={fakeStore(state)}/>),
            example = container.find(Example);

        expect(example.length).to.equal(1);
        expect(example.text()).to.equal(state.firstName);
    });

рдкрд╛рддреНрд░

import React from 'react';
import { connect } from 'react-redux'
import Example from './Example';

const mapStateToProps = (state) => ({
    name: state.firstName
})

export default connect(mapStateToProps)(Example);

рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг

import React, { Component } from 'react';

export default class Example extends Component {
    render(){
        return (
            <div className='example'>
                {this.props.firstName}
            </div>
        )
    }
}

рдЗрд╕реЗ рдЙрдерд▓реЗ рддрд░реАрдХреЗ рд╕реЗ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ, рдбрдмрд▓ рдЙрдерд▓рд╛ рдХрд░рдирд╛ред рдЙрдерд▓реЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдкрд░ рдЙрдерд▓рд╛ рдмрдЪреНрдЪреЗ рдХреЗ рдШрдЯрдХ рдХреЛ рдЙрдерд▓рд╛ рдХрд░ рджреЗрдЧрд╛ рдХрд┐ рдЗрд╕рдХреА рд▓рдкреЗрдЯ, рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реИ:

it('get child component by double shallow()', () => {
        const container = shallow(<ExampleContainer store={fakeStore({})}/>),
            presentationalChildComponent = container.find(Example).shallow().find('.example');

        expect(presentationalChildComponent).to.have.length(1);
    });

рддреЛ рдпрд╣ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ, рдЖрдк рдЕрдкрдиреЗ рдкреНрд░рд╕реНрддреБрддрд┐ рдШрдЯрдХ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

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

рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реИ рдХрд┐ рдЖрдк рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╣реИрдВ рдФрд░ рдореИрдВ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЪреАрдЬреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рдкрд╛рдЧрд▓ рд╣реЛ рд░рд╣реЗ рд╣реИрдВ :)

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

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

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

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

If anyone would like to contribute to that repo, please get a hold of me рддрд╛рдХрд┐ рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕рдореЗрдВ рдПрдХ рд╕рд╣рдпреЛрдЧреА рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХреВрдВред рдореБрдЭреЗ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдХрд┐ рд▓реЛрдЧ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝реЗрдВред рдореИрдВ рдПрдВрдЬрд╛рдЗрдо , рдПрд╡рд╛ , рдЬреЗрд╕реНрдЯ , рдЯреЗрдк рдЗрддреНрдпрд╛рджрд┐ рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рд░рд┐рдПрдХреНрдЯ рдЯреЗрд╕реНрдЯ рдпреВрдЯрд┐рд▓реНрд╕ + рдореЛрдЪрд╛ рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рдирд┐рд╖реНрдХрд░реНрд╖ :

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

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

@markerikson рдЖрдкрдХреЗ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореБрдЭреЗ рдмрд╛рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИред рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИ рдпрд╛рд░ред рдореИрдВ рдЖрдкрдХреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдкрд░ рд╕рд╡рд╛рд▓ рдирд╣реАрдВ рдЙрдард╛ рд░рд╣рд╛ рдерд╛, рдмрд╕ рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реАрдзреЗ mapStateToProps рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХреА рдереА! рдЖрдк рдПрдХ рдЧреИрд░-рдкрд░реАрдХреНрд╖рдХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрд░рд╛ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ;)ред рдореИрдВ рдмрд╕ redux рдХреЗ рд▓рд┐рдП рдирдпрд╛ рд╣реВрдБ, рдЗрддрдирд╛ рд╕рд░рд▓ рдЗрд╕рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рдРрд╕реЗ рдкреНрд░рд╢реНрди рд╣реЛрдВрдЧреЗ рдЬреЛ "рд╕рддрд╣ рдХреЛ рд╕реНрдкрд░реНрд╢ рдХрд░реЗрдВ" рдирд╣реАрдВ рд╣реИрдВред рд╣рдореЗрдВ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рд▓реЛрдЧ рд╕рдордЭ рд╕рдХреЗрдВ рдХрд┐ рд╡реЗ рдХреНрдпрд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡реЗ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рд╡реЗ рдЕрдкрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд▓рд╛рднрд╛рдиреНрд╡рд┐рдд рд╣реЛ рд░рд╣реЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдкрд░ рдХрдиреЗрдХреНрдЯ, рд░рд┐рдПрдХреНрдЯ-рд░реЗрдбрдХреНрд╕, рдкреНрд░рджрд╛рддрд╛ рдХреЛ рд╕рдордЭрдирд╛ рд╣реЛрдЧрд╛ ... рддрд╛рдХрд┐ рдЖрдк рдЬрд╛рди рд╕рдХреЗрдВ рдХрд┐ "рдХреЗрд╡рд▓ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд░реЗрдВ"ред рдореИрдВрдиреЗ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЛ mapStateToProps рдирд┐рд░реНрдпрд╛рдд рдХрд░рддреЗ рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИ рдЬреЛ рдореЗрд░реЗ рд▓рд┐рдП рднреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ ... рдФрд░ рдЗрд╕рд╕реЗ рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпреЛрдВ рдирд╣реАрдВред

WeDoTDD.com
рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП BTW, рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ WeDoTDD.com рд╢реБрд░реВ рдХрд┐рдпрд╛ (React btw рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛)ред рдпрджрд┐ рдХреЛрдИ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЯреАрдо (рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдЯреАрдо рдХреЗ рд╕рднреА рджреЗрд╡) TDD, рдпрд╛ рдЖрдкрдХреА рдкреВрд░реА рдХрдВрдкрдиреА (рдХреБрдЫ рдХрдВрдкрдирд┐рдпреЛрдВ рдХреЗ рдкрд╛рд╕ рдРрд╕реЗ рджреЗрд╡ рд╣реИрдВ рдЬрд╣рд╛рдБ рд╕рднреА TDD рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкрд░рд╛рдорд░реНрд╢ рджреЗрдиреЗ рд╡рд╛рд▓реА рдХрдВрдкрдирд┐рдпрд╛рдБ рд╣реИрдВ), рддреЛ рдХреГрдкрдпрд╛ slack.wedotdd.com рдкрд░ рдореБрдЭрд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░реЗрдВред

рдЕрджреНрдпрддрдиред

рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдФрд░ рдЕрдзрд┐рдХ рдЦреЗрд▓рдиреЗ рдХреЗ рдмрд╛рдж рдФрд░ рдореЗрд░реЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЗрд╕ рдкрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЕрдм @markerikson рдХреЗ рдХрдерди рд╕реЗ 100% рд╕рд╣рдордд рд╣реВрдВ:

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

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

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

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

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

рдПрдХ <Provider> /рд╕рдВрджрд░реНрдн _is_ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдпрджрд┐ рдЖрдк рдПрдХ рдШрдЯрдХ рдХрд╛ рдкреВрд░реНрдг рд░реЗрдВрдбрд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рдЬреБрдбрд╝реЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЬреБрдбрд╝реЗ рд╣реБрдП рдмрдЪреНрдЪреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реНрдЯреЛрд░ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВрдЧреЗред

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд░реАрдХреНрд╖рдг рдкрд░ Redux рдХреЗ рд╡рд░реНрддрдорд╛рди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕реБрдЭрд╛рд╡ рд╣реИрдВ, рддреЛ рд╣рд░ рддрд░рд╣ рд╕реЗ рдПрдХ рдкреАрдЖрд░ рдлрд╝рд╛рдЗрд▓ рдХрд░реЗрдВред

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

рд╡реИрд╕реЗ рднреА рдЕрдЪреНрдЫреА рдЪреАрдЬреЗрдВ, рдзрдиреНрдпрд╡рд╛рдж!

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

(рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЦреБрдж рдХреЛ рджреЛрд╣рд░рд╛ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрд╖рдорд╛ рдХрд░реЗрдВ - рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рдЦрддрд░реЗ рд╣рдореЗрд╢рд╛ рдПрдХ рдзрд╛рдЧреЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ, рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╕реНрдХреНрд░реЙрд▓ рднреА рдХрд░рддреЗ рд╣реИрдВред)

рдЖрд╣ рдареАрдХ рд╣реИ! рд╣рд╛рдБ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪрд╛ ...

рдпрд╣рд╛рдВ рд╕рднреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, @markerikson рдФрд░ @dschinkel! рд╡реЗ рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рд╣реИрдВред рдореИрдВрдиреЗ рдЕрдм рдЕрдкрдиреЗ рдЕрд╕рдВрдмрджреНрдз рдШрдЯрдХ рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рдиреЗ рдФрд░ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреА рддрд░рд╣ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рд╣реИ, рдФрд░ рдЕрдкрдиреЗ mapStateToProps рдФрд░ mapDispatchToProps рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рднреА рдХрд┐рдпрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдРрд╕рд╛ рдорд╛рдорд▓рд╛ рд╣реИ рдЬреЛ рдЗрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдирд╣реАрдВ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рдФрд░ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм map(State/Dispatch)ToProps рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЙрд▓ рдореЗрдВ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ connect ред рдЙрджрд╛рд╣рд░рдг:

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

export const mapStateToProps = ({ name }) => ({ name });

export const Example = ({ name }) => <h1>{name}</h1>;

export default connect({ name } => ({ name: firstName }))(Example); // Whoops, didn't actually pass in `mapStateToProps`.

рдпрд╣ рд╢рд╛рдпрдж рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХрднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ рд▓рд┐рдВрдЯрд░реНрд╕ mapStateToProps рдХреЛ рдЕрдкреНрд░рдпреБрдХреНрдд рдЪрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд░рд┐рдкреЛрд░реНрдЯ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

@ рдбреИрдиреА-рдПрдВрдбреНрд░рдпреВрдЬрд╝ рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ mapDispatchToProps рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ?

@leizard

рдореИрдВ рдЕрдм рд╕реАрдзреЗ mapDispatchToProps рдпрд╛ mapStateToProps рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рддрд╛ред рдореИрдВрдиреЗ рдЗрд╕ рдзрд╛рдЧреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдЕрдкрдирд╛ рд╡рд┐рдЪрд╛рд░ рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдРрд╕рд╛ рди рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

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

рддреЛ рдореИрдВ @markerikson рд╕реЗ рдЕрд╕рд╣рдордд рд╣реВрдВ, рдЕрдкрдиреЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдПрдкреАрдЖрдИ/рдЕрдиреБрдмрдВрдз рдвреВрдБрдврдирд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ, рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрдЪреНрдЪрд╛ рд╣реИ :)ред

@dschinkel

рдЖрдкрдХреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдХреЗ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рд░реВрдк рд╕реЗ рдЙрди рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ...
рддреЛ рдореИрдВ @markerikson рд╕реЗ рдЕрд╕рд╣рдордд рд╣реВрдВ, рдЕрдкрдиреЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

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

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

  1. рдЕрд╕рдВрдмрджреНрдз рдШрдЯрдХ рдФрд░ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ
  2. mapStateToProps рдпрд╛ mapDispatchToProps рдирд┐рд░реНрдпрд╛рдд рди рдХрд░реЗрдВ
  3. рдЕрд╕рдВрдмрджреНрдз рдШрдЯрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рднреА рдШрдЯрдХ рддрд░реНрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ
  4. Redux рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп рдХреЗрд╡рд▓ рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ (рдбреЗрдЯрд╛ рдкреНрд░реЙрдкреНрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдореЗрдВ рдЙрдЪрд┐рдд рд╕реНрдерд╛рди рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ / рдПрдХреНрд╢рди рдкреНрд░реЙрдкреНрд╕ рдХреЛ рдЙрдЪрд┐рдд рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдЖрджрд┐ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред

рдирдВрдмрд░ 4 рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдПрдХрдорд╛рддреНрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдУрд╡рд░рд╣реЗрдб рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЕрдкрдиреЗ рдХрдиреЗрдХреНрдЯреЗрдб рдХрдВрдкреЛрдиреЗрдВрдЯ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░реЗрдбрдХреНрд╕ рд╕реНрдЯреЛрд░ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдирд╛ рд╣реЛрдЧрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреА API рдХреЗрд╡рд▓ рддреАрди рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВред

MapStateToProps рд╡рд┐рдзрд┐

рдЯреЗрд╕реНрдЯрдХрдВрдЯреЗрдирд░.рдЬреЗрдПрд╕рдПрдХреНрд╕:

import { connect } from 'react-redux';

export const TestContainer = ({ permissions }) => (permissions['view-message'] ? 'Hello!' : null);

export const mapStateToProps = ({ auth }) => ({ permissions: auth.userPermissions });

export default connect(mapStateToProps)(TestContainer); // Ewww, exposing private methods just for testing

TestContainer.spec.jsx:

import React from 'react';
import { shallow } from 'enzyme';

import TestContainer, { mapStateToProps } from './TestContainer';

it('maps auth.userPermissions to permissions', () => {
  const userPermissions = {};

  const { permissions: actual } = mapStateToProps({
    auth: { userPermissions },
  });

  expect(actual).toBe(userPermissions);
});

рдирдИ рд╡рд┐рдзрд┐

рдЯреЗрд╕реНрдЯрдХрдВрдЯреЗрдирд░.рдЬреЗрдПрд╕рдПрдХреНрд╕:

import { connect } from 'react-redux';

export const TestContainer = ({ permissions }) => (permissions['view-message'] ? 'Hello!' : null);

const mapStateToProps = ({ auth }) => ({ permissions: auth.userPermissions });

export default connect(mapStateToProps)(TestContainer);

TestContainer.spec.jsx:

import React from 'react';
import { shallow } from 'enzyme';

import TestContainer, { TestComponent } from './TestContainer';

it('renders TestComponent with approriate props from store', () => {
  const userPermissions = {};
  // Stubbing out store. Would normally use a helper method. Did it inline for simplicity.
  const store = {
    getState: () => ({
      auth: { userPermissions },
    }),
    dispatch: () => {},
    subscribe: () => {},
  };
  const subject = shallow(<TestContainer store={store} />).find(TestComponent);

  const actual = subject.prop('permissions');
  expect(actual).toBe(userPermissions);
});

рд╣рд╛рдБ, рдореИрдВ рдпрд╣реА рдХрд╣ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдореИрдВ mapStateToProps рдХрд╛ рдирд┐рд░реНрдпрд╛рдд рдФрд░ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рддрд╛ , рдпрд╣ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред рдпрд╣рд╛рдВ рдПрдкреАрдЖрдИ рдХрдВрдЯреЗрдирд░ рд╣реИред

@ рдбреИрдиреА-рдПрдВрдбреНрд░рдпреВрдЬ

рдЕрд╕рдВрдмрджреНрдз рдШрдЯрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рднреА рдШрдЯрдХ рддрд░реНрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ

рдХреНрдпрд╛ рдЖрдк рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╕рд╛рдЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

рдореЗрд░рд╛ рдорддрд▓рдм рд╡рд╣реА рд╣реИ рдЬреЛ рдЖрдкрдиреЗ рдХрд╣рд╛ рдерд╛ рдЬрдм рдЖрдкрдиреЗ рдХрд╣рд╛ рдерд╛: "рдЖрдкрдХреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдХреЗ рдкрд░реЛрдХреНрд╖ рд░реВрдк рд╕реЗ рдЙрди рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП"

рдпрд╣ рд╢рд░реНрддреЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ: рдЬрдм рдореИрдВ "рдЕрд╕рдВрдмрджреНрдз рдШрдЯрдХ" рдХрд╣рддрд╛ рд╣реВрдВ, рддреЛ рдореЗрд░рд╛ рдорддрд▓рдм рдХрдЪреНрдЪреЗ рдШрдЯрдХ рд╕реЗ рд╣реИ рдЬреЛ рдХреЙрд▓ рдореЗрдВ connect рдкрд░ рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрдм рдореИрдВ "рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ" рдХрд╣рддрд╛ рд╣реВрдВ рддреЛ рдореЗрд░рд╛ рдорддрд▓рдм рдкрд░рд┐рдгрд╛рдореА рдШрдЯрдХ рд╣реИ рдЬреЛ рд╕реЗ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ connect рдкрд░ рдХреЙрд▓ рдХрд░реЗрдВред "рдХрдиреЗрдХреНрдЯреЗрдб рдШрдЯрдХ" рдФрд░ "рдХрдВрдЯреЗрдирд░" рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рдпрд╡рд╛рдЪреА рд╣реИрдВред рдореЗрд░реЗ рдКрдкрд░ рд╕реЗ:

// Unconnected component. Test all component logic by importing this guy.
export const TestComponent = ({ permissions }) => (permissions['view-message'] ? 'Hello!' : null);

const mapStateToProps = ({ auth }) => ({ permissions: auth.userPermissions });

// Connected component (container). Only test interaction with redux by importing this guy.
export default connect(mapStateToProps)(TestComponent);

рдХреБрдЫ рд▓реЛрдЧ рдЗрдиреНрд╣реЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЙрдирдХреЗ "рдХрдВрдЯреЗрдирд░" рдХреЛ рдХреЗрд╡рд▓ connect рдкрд░ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рд╕реНрддреБрддрд┐ рдШрдЯрдХ рдХреЛ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВред рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕реВрдЪреА рдореЗрдВ рдирдВрдмрд░ 1 рдФрд░ 3 рдЪрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рд╡рд╣реА рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рд░реЗрдбрдХреНрд╕ (рд╕рдВрдЦреНрдпрд╛ 4) рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рдореИрдВ рдЗрд╕ рдкрд░ рдПрдХ рдмрдбрд╝рд╛ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рд▓рд┐рдЦрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВ рдЗрд╕ рд╕рдордп рдХреЛрдб рдореЗрдВ рд╡реНрдпрд╕реНрдд рд╣реВрдВ рд▓реЗрдХрд┐рди рдмрд╛рдж рдореЗрдВ рдЬрд╡рд╛рдм рджреВрдВрдЧрд╛

рдЗрд╕ рд╕реВрддреНрд░ рдХреЛ рдХрдИ рдмрд╛рд░ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЗрд╕ рдирд┐рд╖реНрдХрд░реНрд╖ рдкрд░ рдкрд╣реБрдВрдЪрд╛ рдХрд┐ 3 рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реБрдЭрд╛рдП рдЧрдП рд╣реИрдВ:

  1. mapDispatchToProps рдФрд░ mapStateToProps рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ рдФрд░ рдЙрдирдХрд╛ рдЕрд▓рдЧ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ
  2. рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдХреЛ рдЙрдерд▓рд╛ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ рдХрд┐ рд╡рд╛рдпрд░рд┐рдВрдЧ рд╕рд╣реА рд╣реИ
  3. mapStateToProps рдХреЗ рдмрдЬрд╛рдп рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдФрд░ mapDispatchToProps рдХреЗ рдмрдЬрд╛рдп рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдЙрдирдХрд╛ рдЕрд▓рдЧ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ; рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕рдВрдкреВрд░реНрдг рдкреНрд░рд╡рд╛рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕, рд░рд┐рдбреНрдпреВрд╕рд░ рдФрд░ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВред

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

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

рдЗрд╕рд▓рд┐рдП рдореИрдВ @dschinkel рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдУрд░ рдЭреБрдХ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдирдХреНрд╢рд╛ рдбрд┐рд╕реНрдкреИрдЪ рдФрд░ рдореИрдкрд╕реНрдЯреЗрдЯ рдирд┐рд░реНрдпрд╛рдд рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рд▓рд┐рдП рд╡реЗ рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдХреЗ рдирд┐рдЬреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВред

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

рдХреНрдпрд╛ рдЖрдкрдиреЗ рдХрднреА рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рд▓рд┐рдЦрд╛ рд╣реИ? @dschinkel рдЗрд╕реЗ рдкрдврд╝рдирд╛ рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗ

@AnaRobynn

рд╣рд╛рдБ, рдореИрдВ рдЖрдкрд╕реЗ рд╕рд╣рдордд рд╣реВрдБ рдХрд┐ рдХреЗрд╡рд▓ mapDispatch рдФрд░ mapState рдирд┐рд░реНрдпрд╛рдд рдХрд░рдирд╛ рдЧрд▓рдд рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рд╢рд╛рдпрдж рд╕реНрд╡рдпрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реВрдБрдЧрд╛, рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдПрдХ рд╡реИрдз рд╡рд┐рдХрд▓реНрдк рд╣реИ, рднрд▓реЗ рд╣реА рдХрдо "рд╢реБрджреНрдз" рд╡рд┐рдХрд▓реНрдк рд╣реЛ . рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рднреА рд╡рд╣реАрдВ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдбреИрди рдЕрдмреНрд░рд╛рдореЛрд╡ рдиреЗ рдпрд╣рд╛рдВ рдЗрд╕ рд╕рдЯреАрдХ рддрдХрдиреАрдХ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдерд╛: https://github.com/reduxjs/react-redux/issues/325#issuecomment -199449298ред

"рдПрдХ рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рдХреЗрд╡рд▓ рдПрдХ рдХрдиреЗрдХреНрдЯ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рдФрд░ рдШрдЯрдХ рд▓рдкреЗрдЯрддрд╛ рд╣реИ" рдХреЗ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рди рдХрд░реЗрдВред рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдИ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЖрдк connect рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рдЬрд┐рд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдкрд╣рд▓реЗ рд╣реА react-redux рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИред

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

@ucorina рдмрд┐рд▓реНрдХреБрд▓, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рдХрд▓реНрдк рд╡рд╣ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдореИрдВ рднреА рдЬрд╛рдКрдВрдЧрд╛! рдЕрдкрдиреЗ рдЙрддреНрддрд░ рдХреЛ рдЕрдзрд┐рдХ рдЧрд╣рд░рд╛рдИ рд╕реЗ рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдпрд╣ рдПрдХ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦреА рдЧрдИ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рд╣реИред рдмрдзрд╛рдИ!

@ucorina рдлрд┐рд░ рд╕реЗ рдкрд░реЗрд╢рд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ, рд▓реЗрдХрд┐рди рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдП рд╕реЛрдиреЗ рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд╡рд┐рдХрд▓реНрдк 2 рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕рд╣рдордд рд╣реВрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред рдореИрдВ mapStateToProps рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд╛рдн рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдареАрдХ рд╣реИ рдХрд┐ "рд╡рд┐рдХрд▓реНрдк 2", рдкрд░реЛрдХреНрд╖ рд░реВрдк рд╕реЗ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рднреА рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реИ? рдФрд░ рдкрд░реЛрдХреНрд╖ рд░реВрдк рд╕реЗ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рднреА? рдХреНрдпрд╛ рд╡рд╣ рдЕрдЪреНрдЫреА рдЪреАрдЬрд╝ рд╣реИ?
рдореИрдВ рдЗрд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ 100% рдЖрд╢реНрд╡рд╕реНрдд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╡рд╣рд╛рдВ рд╕рднреА (рдЧрд▓рдд) рд╕реВрдЪрдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рднреНрд░рдорд┐рдд рд╣реВрдВред рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рдЪрд╛рд░ рд╣реИрдВред

  1. рдХреЗрд╡рд▓ mapStateToProps рдХреЗ рдЕрдВрджрд░ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

    • рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдХрдВрдЯреЗрдирд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рдЙрдирдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВ

    • рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЕрд▓рдЧ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

    • рдХреЗрд╡рд▓ mapDispatchToProps рдХреЗ рдЕрдВрджрд░ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

    • рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдХрдВрдЯреЗрдирд░ рдЯреЗрд╕реНрдЯ рдХреЗ рджреМрд░рд╛рди рдЙрдирдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВред

    • рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рдЕрд▓рдЧ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

    • рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдШрдЯрдХ рдЙрдерд▓рд╛ рд╣реИ

    • рдЬреЛрд░ рджреЗрдХрд░ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ

    • рдХрд┐рд╕реА рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ рдЬрд┐рд╕реЗ mapStateToProps , mapDispatchToProps рдпрд╛ mergeProps рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдерд╛ рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рдХрд╣реАрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред (рд╕рд╢рд░реНрдд рдкреНрд░реЗрд╖рдг, рдЪрдпрдирдХрд░реНрддрд╛ рдЬреЛ ownProps , рдЖрджрд┐ рд╕реЗ рддрд░реНрдХ рд▓реЗрддреЗ рд╣реИрдВ)



      • рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрдк рдХреЗрд╡рд▓ рдЙрди рдореЙрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рд╣реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдФрд░ рд╕рд╣реА рдЖрд░реНрдЧ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред



рд╡рд┐рдХрд▓реНрдк:

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

@AnaRobynn рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ @ucorina рдХрд╛ рджреВрд╕рд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рд╣реА рд╣реИред

рдЬреЛ рдХреБрдЫ рдореИрдВ рд╕реБрдирддрд╛ рд╣реВрдВ рд╡рд╣ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИ:

  1. рдЖрдкрдХреЛ mapDispatchToProps рдХрд╛ рдкрд░реНрджрд╛рдлрд╛рд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╕реАрдзреЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
  2. рдХрдиреЗрдХреНрдЯ () рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЕрдкрдиреА рдХреЙрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдХрдиреЗрдХреНрдЯ () рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

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

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

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдареАрдХ рд╣реИ рдХрд┐ "рд╡рд┐рдХрд▓реНрдк 2", рдкрд░реЛрдХреНрд╖ рд░реВрдк рд╕реЗ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рднреА рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реИ? рдФрд░ рдкрд░реЛрдХреНрд╖ рд░реВрдк рд╕реЗ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рднреА? рдХреНрдпрд╛ рд╡рд╣ рдЕрдЪреНрдЫреА рдЪреАрдЬрд╝ рд╣реИ?

рд╣рд╛рдВ, рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдПрдХ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИред

@philihp @dougbacelar
рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдореИрдВ рд░рд┐рдПрдХреНрдЯ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдереЛрдбрд╝рд╛ рд╕рдВрдмрдВрдзрд┐рдд рд╣реВрдВред рдореЗрд░реЗ рд╡рд░реНрддрдорд╛рди рд╡рд┐рд╢реНрд╡рд╛рд╕ рдФрд░ рд╡рд┐рд╖рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рдЪрд╛рд░:

  1. рдпрджрд┐ рдЖрдкрдХреЛ рдХрдИ рдШрдЯрдХреЛрдВ рдореЗрдВ рдЙрди рдореИрдкрд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ mapStateToProps рдФрд░ mapDispatchToProps рдХреЛ рдЙрдЬрд╛рдЧрд░ рди рдХрд░реЗрдВред рдЙрдиреНрд╣реЗрдВ рд╕рд┐рд░реНрдл рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдпрд╛рдд рдХрд░рдирд╛ рдПрдХ рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди рд╣реИред
  2. рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ (рдХрд╛рд░реНрдп рдЬреЛ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реМрдВрдкрддреЗ рд╣реИрдВ рдФрд░ рд╡реЗ рдЕрдиреНрдп рдХрд╛рд░реНрдп рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддрд░реНрдХ рдХрд░рддреЗ рд╣реИрдВ)ред
    рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ?
  3. рдХрдВрдЯреЗрдирд░ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ
  4. рд░рд╛рдЬреНрдп рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХрд╛ рддрд░реНрдХ рдЪрдпрдирдХрд░реНрддрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ (рдЬреЛ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)
  5. рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдореЗрдВ рдПрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдЫрд┐рдкреЗ рд╣реЛрддреЗ рд╣реИрдВ (рдЬреЛ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд░реЗрдбрдХреНрд╕-рдердВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВ, рдЖрдк рд╕реНрд╡рдпрдВ рд╕рд╣рдпреЛрдЧреА рд╣реИрдВ)
  6. рдкреНрд░рд╕реНрддреБрдд рджреГрд╢реНрдп рдПрдХ рдЕрдиреНрдп рдХрд╛рд░реНрдп рд╣реИ (рдЬрд┐рд╕рдореЗрдВ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдЕрдиреНрдп рд╕рд╣рдпреЛрдЧреА рдХрд╛рд░реНрдп рд╣реИ рдпрд╛ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╕рд╛рдорд╛рди рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ

=> рдЬрдм рдЖрдк рдЙрдЪрд┐рдд рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯрдЕрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реЛрддрд╛ рд╣реИ (рдореИрдВ testdouble.js рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ)ред
=> testdouble.js рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдкрдиреЗ рдЪрдпрдирдХрд░реНрддрд╛ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВ ( td.when() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)
=> рдЕрдкрдиреЗ рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдХреЛ рдЙрдерд▓рд╛ рд░реЗрдВрдбрд░ рдХрд░реЗрдВ, dive() рдПрдХ рдмрд╛рд░ рджреГрд╢реНрдп рдШрдЯрдХ рдХреЗ рддрд░реАрдХреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
=> рдирд┐рдпрдореЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП td.when() рдЕрдЧрд░ рдШрдЯрдХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ рддреЛ рдЬреЛрд░ рджреЗрдВ

рдХреБрдЫ рдирдХрд▓реА рд╕реНрдЯреЛрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕реНрдЯреЛрд░ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдирд╛ рдареАрдХ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:

/** <strong i="27">@format</strong> */

import React from 'react';
import { shallow } from 'enzyme';

function setup(props) {
  const HasOrganization = require('./HasOrganization').default;
  const defaultProps = {
    store: {
      subscribe: Function.prototype,
      getState: Function.prototype,
      dispatch: Function.prototype,
    },
  };
  const container = shallow(<HasOrganization {...defaultProps} {...props} />);
  return {
    container,
    wrapper: container.dive(),
  };
}

describe('<HasOrganization /> collaborations', () => {
  let getCurrentOrganizationId;
  beforeEach(() => {
    getCurrentOrganizationId = td.replace('../containers/App/userSelectors')
      .selectCurrentOrganizationId;
  });

  test('not render anything when the id is not valid', () => {
    const Dummy = <div />;
    td.when(getCurrentOrganizationId()).thenReturn(null);
    const { wrapper } = setup({ children: Dummy });

    expect(wrapper.find('div').length).toBe(0);
  });

  test('render something when the id is valid', () => {
    const Dummy = <div />;
    td.when(getCurrentOrganizationId()).thenReturn(1);
    const { wrapper } = setup({ children: Dummy });

    expect(wrapper.find('div').length).toBe(1);
  });
});

рд╡рд┐рдЪрд╛рд░?

@AnaRobynn рдЕрдВрдХ 1 рдФрд░ 2 рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕рд╣рдордд рд╣реИрдВ!

рдореЗрд░реЗ рдХрдВрдЯреЗрдирд░ рдЖрдорддреМрд░ рдкрд░ рдмрд╣реБрдд рд╕реАрдзреЗ рдЖрдЧреЗ рд╣реЛрддреЗ рд╣реИрдВ:

// imports hidden

const mapStateToProps = (state, { userId }) => ({
  isLoading: isLoading(state),
  hasError: hasError(state),
  placeholders: getPlaceholders(userId)(state), // a list of some sort
  shouldDoStuff: shouldDoStuff(state),
});

const mapDispatchToProps = {
  asyncActionPlaceholder,
};

export const mergeProps = (stateProps, dispatchProps, ownProps) => {
  return {
    ...stateProps,
    ...dispatchProps,
    ...ownProps,
    onMount: () => {
      if (stateProps.shouldDoStuff) {
        dispatchProps.asyncActionPlaceholder(ownProps.userId);
      }
    },
  };
};

export default compose(
  connect(
    mapStateToProps,
    mapDispatchToProps,
    mergeProps
  ),
  callOnMount(props => props.onMount())
)(SampleComponent);

рддреЛ рдореИрдВ

  1. рд╕рднреА рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдФрд░ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░ рдХреА рдЬрд╛рд╕реВрд╕реА рдХрд░реЗрдВ
  2. рдкрд░реАрдХреНрд╖рдг getPlaceholders рдЬрд╛рд╕реВрд╕ рдХреЛ рд╕рд╣реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛
  3. рдореБрдЦрд░ SampleComponent рдХреЛ рд╕рд╣реА рдкреНрд░реЙрдкреНрд╕ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛
  4. onMount рдкреНрд░реЛрдк рдХреЛ SampleComponent рд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдирдХрд▓реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрддрд╛ рд╣реИ рдЬрдм shouldDoStuff===true
  • рдкреНрд░реЙрдкреНрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рд╛рдорд╛рди рдХреЗ рд╕рд╢рд░реНрдд рдкреНрд░рддрд┐рдкрд╛рджрди рдЬреИрд╕реА рдЪреАрдЬреЗрдВ рдореИрдВ SampleComponent . рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░реВрдВрдЧрд╛
  • рдореИрдВ рд╕реНрдЯреЛрд░ рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП redux-mock-store рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ рдЬреИрд╕реЗ configureMockStore([thunk])() рд▓реЗрдХрд┐рди рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдареАрдХ рд╣реИ ...

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

@philihp

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

@dougbacelar рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рджреНрд╡рд╛рд░рд╛ рджрд┐рдЦрд╛рдП рдЧрдП рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдирдореВрдирд╛ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдПрдВрдЬрд╛рдЗрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ? рдХреБрдЫ рдФрд░? рдЙрдерд▓рд╛? рдорд╛рдЙрдВрдЯ?

@dougbacelar

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

рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЕрд╕рд▓реА рдЪреАрдЬ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпреЛрдВ рдирд╣реАрдВ? рдЬрдм рдХреБрдЫ рдХреЙрд▓ рдзреАрдореА рд╣реЛрддреА рд╣реИрдВ, рдпрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдЬреИрд╕реЗ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ рддреЛ рдореЙрдХрд┐рдВрдЧ рдЙрдкрдпреЛрдЧреА рд╣реЛрддреА рд╣реИред

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

рд╣рд╛рдВ , рдЕрдкрдиреЗ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ, рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░реНрд╕ рдХрд╛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдЗрдирдкреБрдЯ рдХреЗ рд╕рд╛рде рдЙрдирдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

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

рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ...

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { saveColor } from '../actions/save';
import { selectColors } from '../reducers/colors.js';
import ColorButtons from '../components/ColorButtons';
const ColorButtons = ({ colors, onClick }) => (
  <div>
    {colors.map(color => {
      <button type="button" key={color} onClick={onClick(color)}>{color}</button>
    })}
  </div>
);
ColorButtons.propTypes = {
  colors: PropTypes.arrayOf(PropTypes.string),
  onClick: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
  colors: selectColors(state.colors),
});
const mapDispatchToProps = dispatch => ({
  onClickColor: color => () => {
    dispatch(saveColor({ color }));
  },
});
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ColorButtons);
import React from 'react';
import { shallow } from 'enzyme';
import configureStore from 'redux-mock-store';
import ColorButtons from '../ColorButtons';
import { saveColor } from '../../actions/save';
import { selectColors } from '../../reducers/colors.js';
const buildStore = configureStore();
describe('<ColorButtons />', () => {
  let store;
  let wrapper;
  const initialState = { colors: ['red', 'blue'] };
  beforeEach(() => {
    store = buildStore(initialState);
    wrapper = shallow();
  });
  it('passes colors from state', () => {
    expect(wrapper.props().colors).toEqual(selectColors(initialState.colors));
  });
  it('can click yellow', () => {
    const color = 'yellow';
    wrapper.props().onClick(color)();
    expect(store.getActions()).toContainEqual(saveColor({ color }));
  });
});

рдпрд╣рд╛рдВ, рдпрд╣ рдЙрди рд╕рднреА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреИрд░рд╛рдореНрд╕ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ selectColors рдФрд░ saveColor рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ; рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдЬрдм <ColorButtons /> рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рд╡реЗ рдЧреБрдг рдорд┐рд▓рддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдо рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВред рдХрд┐рд╕реА рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдЙрдирдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред

import { selectColors } from '../colors.js';
describe('selectColors', () => {
  it('returns the colors', state => {
    expect(selectColors(['red'])).toEqual(['red'])
  })
  it('returns an empty array if null', state => {
    expect(selectColors(null)).toEqual([])
  })
  it('returns a flattened array', state => {
    expect(selectColors(['red', ['blue', 'cyan']])).toEqual(['red','blue','cyan'])
  })
})

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

рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЕрд╕рд▓реА рдЪреАрдЬ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпреЛрдВ рдирд╣реАрдВ? рдЬрдм рдХреБрдЫ рдХреЙрд▓ рдзреАрдореА рд╣реЛрддреА рд╣реИрдВ, рдпрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдЬреИрд╕реЗ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ рддреЛ рдореЙрдХрд┐рдВрдЧ рдЙрдкрдпреЛрдЧреА рд╣реЛрддреА рд╣реИред

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

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

рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ...

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

рдпрд╣ рдереНрд░реЗрдб https://martinfowler.com/articles/mocksArentStubs.html , рдХреНрд▓рд╛рд╕рд┐рдХрд▓ рдФрд░ рдореЙрдХрд┐рд╕реНрдЯ рдЯреЗрд╕реНрдЯрд┐рдВрдЧ рдореЗрдВ рдмрдирд╛рдП рдЧрдП рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд░реАрд╣реИрд╢ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдорд╛рдирд╛ред рддрд╛рд▓рд╛ рд▓рдЧрд╛рдирд╛ред

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

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

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

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

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

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

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