Redux: рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рд▓реЙрдЧрд┐рди/рд╕рд╛рдЗрдирдЕрдк рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕

рдХреЛ рдирд┐рд░реНрдорд┐рдд 22 рдЬреБрд▓ре░ 2015  ┬╖  66рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: reduxjs/redux

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЬреЛ рдореИрдВ рдпрд╣рд╛рдВ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдлреЙрд░реНрдо рд╡рд╛рд▓рд╛ рдкреГрд╖реНрда рд╣реЛрддрд╛ рд╣реИ рддреЛ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛ рд╣реИред рдлрд╝реЙрд░реНрдо рд╕рдмрдорд┐рдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЖрдк рдпрд╛ рддреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреГрд╖реНрда рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ ред

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


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

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

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

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

рдЕрдм рддрдХ рдЖрдкрдХреЗ рдкрд╛рд╕ рдпрд╣ рдкреНрд░рд╡рд╛рд╣ рд╣реИ (рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ):

  • рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ / . рдкрд░ рдЬрд╛рдПрдВ
  • /login . рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВ
  • рдлреЙрд░реНрдо рднрд░реЗрдВ рдФрд░ рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВ
  • рдЕрдЧрд░ рдареАрдХ рд╣реИ рддреЛ / (рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреЗрдЬ) рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВ
  • рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рдкрд░ рд▓реЙрдЧрд┐рди рдлреЙрд░реНрдо рдкрд░ рдмрдиреЗ рд░рд╣реЗрдВ рдФрд░ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдПрдВ

рдЕрдЧрд░ рд╣рдо рдЗрд╕ рдкреНрд░рд╡рд╛рд╣ рдХреЛ redux рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдирд┐рдореНрди рд╕реЗрдЯрдЕрдк рд╣реИ:

// actions
function login (form) {
  return dispatch => doLogin(form)
    .then(() => dispatch({ type: 'LOGGED_IN' }))
    .catch(() => dispatch({ type: 'LOGIN_FAILED' }))
}

// reducer
const initialState = {
  // some fields...,
  loggedIn: false,
  shouldRedirect: false,
  errorMessage: null
}
function application (state = initialState, action) {
  switch action.type {
    case 'LOGGED_IN':
      return Object.assign({}, state, { loggedIn: true, shouldRedirect: true })
    case 'LOGIN_FAILED':
      return Object.assign({}, state, { loggedIn: false, shouldRedirect: false, errorMessage: action.error.message })
  }
  return state
}

// component
@connect(state => { application: state.application })
class Login extends React.Component {
  componentWillUpdate () {
    const { router } = this.context
    const { application } = this.props
    if (application.shouldRedirect)
      router.transition(...)  
  }

  onSubmit () {
    const actions = bindActionCreators(applicationActions, dispatch)
    actions.login({...})
  }

  render () {
    const { errorMessage } = this.props
    return (
      <div>
        {errorMessage ? <p>{errorMessage}</p> : null}
        <Form {...props} onSubmit={onSubmit}>
          {...}
        </Form>
      </div>
    )
  }
}

рдпрд╣ рдкреНрд░рд╡рд╛рд╣ рд╕рд╣реА рд╣реИ - рдЙрдореНрдореАрдж рд╣реИ :) - рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдЖрд╡реЗрджрди рд╕реНрдерд┐рддрд┐ рдореЗрдВ 2 рдЭрдВрдбреЗ рд╣реИрдВ: shouldRedirect рдФрд░ errorMessage ред
рдЙрди рдЭрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рддреЗ рд╕рдордп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдкрд╣рд▓рд╛ рдкреНрд░рд╢реНрди: рдХреНрдпрд╛ рдЙрди рдЭрдВрдбреЛрдВ рдХреЛ рдЖрд╡реЗрджрди рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд░рдЦрдирд╛ рдареАрдХ рд╣реИ?

рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдПрдХ рдФрд░ рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдореИрдВ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рдЙрди рдЭрдВрдбреЛрдВ рдХреЛ "рд░реАрд╕реЗрдЯ" рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рдореИрдВ рджреВрд╕рд░реЗ рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ (рдЬреИрд╕реЗ рд╕рд╛рдЗрдирдЕрдк, ...) рддреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рдл рд╕реНрдерд┐рддрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП ( { shouldRedirect: false, errorMessage: null } )ред

рддреЛ рдореИрдВ рдПрдХ рдФрд░ рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрдирд╛ рдЪрд╛рд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдЬреИрд╕реЗ

// actions
function resetSubmitState () {
  return { type: 'RESET_SUBMIT' }
}

// component
componentWillUpdate () {
  const { store, router } = this.context
  const { application } = this.props
  if (application.shouldRedirect) {
    store.dispatch(applicationActions.resetSubmitState())
    router.transition(...)  
  }
}

рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЛ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реБрдИ рд╣реИ? рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ рдпрд╛ рдпрд╣ рдХрд░рдиреЗ рдХрд╛ "рд╕рд╣реА" рддрд░реАрдХрд╛ рд╣реИ?

рдХреНрдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ?

рдХрд┐рд╕реА рднреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдмрд╣реБрдд рд╕реНрд╡рд╛рдЧрдд рд╣реИ! :)

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

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд╡рд╛рд▓ рдереЛрдбрд╝рд╛ рдФрд░ рдЧрд╣рд░рд╛ рд╣реИ рддреЛ рдмрд╕ 'рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░реЗрдВ' рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ - рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд░рд╛рдЬреНрдп рдХреНрдпрд╛ рд╣реИ рдФрд░ рдХреМрди рд╕рд╛ рдбреЗрдЯрд╛ store рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХреМрди рд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╣реИред

рдореБрдЭреЗ рдлреНрд▓рдХреНрд╕ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЗ View рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╢реБрджреНрдз рдХрд╛рд░реНрдп render(state): DOM рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЛрдЪрдирд╛ рдкрд╕рдВрдж рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред
рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░рд▓ рд░реВрдк рдШрдЯрдХ рд▓реЗрддреЗ рд╣реИрдВ рдЬреЛ рджреЛ рдЗрдирдкреБрдЯ рдлрд╝реАрд▓реНрдб рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ:

class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
      </form>
    )
  }
}

рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рдЖрдВрддрд░рд┐рдХ рд╕реНрдерд┐рддрд┐ рд╕рдВрд╢реЛрдзрди рдХрд┐рдП рдЧрдП рддрд╛рдХрд┐ рдЕрдВрдд рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрдЧрд╛:

{
  name: 'John'
  surname: 'Snow'
}

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

рдЖрдЗрдП рдорд╛рди рд▓реЗрдВ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдкрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рдкреНрд░рдкрддреНрд░ рд╣реИред рдЕрдм рд╣рдореЗрдВ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рд╣рдо рдЗрд╕реЗ рдЕрдкрдиреА рд╡рд┐рд╢реЗрд╖ рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░реЗрдВрдЧреЗред

import { subscribe } from 'actions'

class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  onSubmit (event) {
    event.preventDefault()
    const { name, surname, email } = this.state
    subscribe(name, surname, email)
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
      </form>
    )
  }
}

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

  render () {
    //provided by connector of whatever
    const { props: { isLoading, error } } = this
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}
        disabled={isLoading}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
        {error ? <p>{ error }</p> : null}
      </form>
    )
  }

рд▓реЗрдХрд┐рди рдпрд╣рд╛рдБ рд╢реИрддрд╛рди рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ: рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдпрд╣ рдкреГрд╖реНрда рд╕реНрдерд┐рддрд┐ рдмрдиреА рд╣реБрдИ рд╣реИ рдФрд░ рдЕрдЧрд▓реА render(state) рдХреЙрд▓ рдПрдХ рдЧрдВрджреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдлреЙрд░реНрдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдлреЙрд░реНрдо рдорд╛рдЙрдВрдЯ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП cleanup рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореМрдЬреВрдж рдкреНрд░рддреНрдпреЗрдХ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рд╣рдо рд╕реНрдЯреЛрд░/рд░реЗрдбреНрдпреВрд╕рд░ рдХреЗ рд╕рд╛рде loading , submitted , failed рдФрд░ cleanup рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╣реА рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗтАж рдЙрд╕ рд░рд╛рдЬреНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд┐рд╕реЗ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ submitted рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдпрд╛ рдпрд╣ рдХреЗрд╡рд▓ рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рд╣реИ, рдЬреИрд╕реЗ name рдлрд╝реАрд▓реНрдб рдорд╛рдиред рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╢ рдореЗрдВ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдЬрдм рд╡рд╣ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рджреЗрдЦрддрд╛ рд╣реИ рддреЛ рд╡рд╣ рд╕рд╛рдл рдлреЙрд░реНрдо рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ? рдЙрддреНрддрд░: рдпрд╣ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред

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

рддреЛ рдХреИрд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдореЗрдВ рдШрдЯрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд╣реАрдВ рдФрд░ рдЗрд╕ рд░рд╛рдЬреНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ? рдЖрдЗрдП рдЗрд╕реЗ рдПрдХ рдмрд╛рд░ рдЖрдЬрд╝рдорд╛рдХрд░ рджреЗрдЦрддреЗ рд╣реИрдВред
рдЕрдзрд┐рдХ рдлреИрдВрд╕реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ 2015 рдореЗрдВ рд╣рдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд░рд╣рддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рд░ рдЬрдЧрд╣ Promises рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ Promise рд▓реМрдЯрд╛рдПрдВ:

function subscribe (name, surname, email) {
  return api.request('/subscribtions', 'create', { name, surname, email })
}

рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ Component рдореЗрдВ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

onSubmit (event) {
  event.preventDefault()
  const { name, surname, email } = this.state
  subscribe(name, surname, email)
    .then(() => { this.setState({ submitted: true }) })
    .catch(error => { this.setState({ error }) })
}

componentWillUpdate (object nextProps, object nextState) {
  if(nextState.submitted)
    redirect('somewhere')
}

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдШрдЯрдХ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдм рдХреБрдЫ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рд╛рдл рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИред
рддреЛ рд╣рдо рд▓рдЧрднрдЧ рд╡рд╣рд╛рдБ рд╣реИрдВред рдЕрдм рд╣рдо Component рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЪрд┐рдВрддрд╛рдУрдВ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдХрд╛рд░реНрд░рд╡рд╛рдИ рдФрд░ рд░рд╛рдЬреНрдп рдЕрджреНрдпрддрди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдирд╛:
(рд░реЗрдкреЛ рд╕реАрдорд╛ рдореЗрдВ рдмрдиреЗ рд░рд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ redux рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ)

import React, { PropTypes } from 'react'
import { bindActionCreators } from 'redux'

// Keeps track of action
export default function connectSubmitForm (Form, submitAction) {
  return React.createClass({
    contextTypes: {
      //redux Store
      store: PropTypes.object.isRequired
    },

    getInitialState () {
      return {}
    },

    onSubmit (...args) {
      const { context: { store: { dispatch } } } = this
      const { submitAction: submit }
        = bindActionCreators({ submitAction }, dispatch)
      submit(...args)
        .then(() => this.setState({ submitted: true }))
        .catch(error => this.setState({ error }))
    },

    render () {
      const {
        onSubmit,
        props,
        state: { submitted, error }
      } = this
      return (<Form {...props} onSubmit={onSubmit} submitted={submitted}
        error={error} />)
    }
  })
}

рддрдерд╛

// redirect to path if predicate returns true
export default function redirect (path, predicate) {
  return Component =>
    class Composed extends React.Component {

      componentWillMount () {
        if (predicate(props))
          redirectTo(path)
      }

      componentWillReceiveProps (nextProps) {
        if (predicate(nextProps))
          redirectTo(path)
      }

      render () {
        return <Component {...this.props} />
      }
    }
}

//redirect to path if submitted
export default function redirectSubmitted (path) {
  return redirect(path, ({ submitted }) => submitted)
}

рдЕрдм рдПрдХ рддрд░рдл рд╣рдорд╛рд░реЗ рдкрд╛рд╕ decorator рд╣реИ рдЬреЛ submitted рдФрд░ error рдкреНрд░реЛрдк рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ onSubmit рдХреЙрд▓рдмреИрдХ рдХреЗ рд╕рд╛рде рдФрд░ рджреВрд╕рд░реА рддрд░рдл decorator рдЬреЛ рдХрд╣реАрдВ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ рдЕрдЧрд░ рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ submitted === true ред рдЖрдЗрдП рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдлреЙрд░реНрдо рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИред

@redirectSubmitted('/')
class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  onSubmit (event) {
    event.preventDefault()
    const { name, surname, email } = this.state
    this.props.onSubmit(name, surname, email)
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
        {this.props.error ? <p>{ this.props.error }</p>: null}
      </form>
    )
  }
}

export default submitForm(Form, subscribe)

рдФрд░ рдпрд╣рд╛рдВ рдпрд╣ рд╣реИ: routing рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдХреЛрдИ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде рд╢реБрджреНрдз рд░реЗрдВрдбрд░ рдлреЙрд░реНрдо, flux рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдПрдкреНрд▓рд┐рдХреЗрд╢рди state , рдЬреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛: рд╕рдмрдорд┐рдЯ рдФрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВред

рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдФрд░ рдЕрдкрдирд╛ рд╕рдордп рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред

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

рд╡рд╣рд╛рдВ shouldRedirect рд╣реЛрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╕рддреНрд░ рд░реЗрдбреНрдпреВрд╕рд░ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдЬреЛ рд╕рд┐рд░реНрдл isLoggedIn рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ? рдЗрд╕ рддрд░рд╣ рдЖрдк $#$ shouldRedirect $#$ рдХреЗ рдмрдЬрд╛рдп isLoggedIn рдЪреЗрдХ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд▓реЙрдЧрд┐рди рдкреЗрдЬ рд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреЗрдЬ рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рд╛рде рд╣реА, рдЖрдкрдХреЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдореЗрдВ рдХреЗрд╡рд▓ LOGGED_IN рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдХреЗ рд░рд╛рдЬреНрдп рдХреЛ рд░реАрд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рд╡рд╣ рдХреНрд░рд┐рдпрд╛ рд╣реЛрддреА рд╣реИ рддреЛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рддреНрд░реБрдЯрд┐ рд╕реНрдерд┐рддрд┐ рдХреЛ null рдорд╛рди рдкрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд░реАрд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рднреА рд╣реИ рдХреНрдпрд╛? :рдбреА

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

рдФрд░ рдЙрди рдЭрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрди рд╕рднреА рдкреГрд╖реНрдареЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЙрди рд╕рднреА рдХрд╛ рдкреНрд░рд╡рд╛рд╣ рд╕рдорд╛рди рд╣реИред

рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдм рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ :)

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

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

рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рд░рд╛рдЬреНрдп рд╕рдорд╛рд╢реЛрдзрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рди рд╣реИред рдореБрдЭреЗ рдЕрднреА рддрдХ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рдХреЛ рдПрдХ рдЕрдЪреНрдЫреЗ рддрд░реАрдХреЗ рд╕реЗ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПред

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

@gaearon рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рд╕рдордп рд╣реИ рддреЛ рдореБрдЭреЗ рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреА рд╕реБрдирдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред рдзрдиреНрдпрд╡рд╛рдж! :+1:

рдореЗрд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдореИрдВ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдореЗрдВ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдореИрдВ рдХрд┐рд╕реА рднреА рдЭрдВрдбреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рдореИрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред

// action

/**
 * Creates login action
 *
 * <strong i="6">@param</strong> {string} email
 * <strong i="7">@param</strong> {string} password
 *
 * <strong i="8">@returns</strong> {{types: *[], promise: *}}
 */
export function login(email, password) {
    return {
        types: [LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE],
        promise: post('/login').send({ email: email, password: password }).promise()
    };
}

// auth middleware 
/**
 * Intercepts LOGIN action and redirects to login screen
 * Otherwise just sends action to next middleware
 *
 * <strong i="9">@returns</strong> {Function}
 */
function authMiddleware({getState, dispatch}) {
    return (next) => (action) => {
        if (typeof action === 'object' && action.hasOwnProperty('type')) {
            if (action.type === LOGIN_SUCCESS) {
                next(action); // send it to next so identity will be set

                // get current route
                const state = getState();
                let path = '/dashboard';

                if (typeof state['router'] === 'object' && typeof state['router']['route'] === 'object' && null !== state['router']['route']) {
                    if (state.router.route.name === 'login' && typeof state.router.route.query['to'] === 'string') {
                        path = state.router.route.query.to;
                    }
                }

                return next(actions.transitionTo(path));
            }
        }

        return next(action);
    };
}

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

рдпрд╣ рдореЗрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдПрдХ рдХреЙрдкреА рдФрд░ рдкреЗрд╕реНрдЯ рд╣реИ рдФрд░ рдореИрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рд▓реЙрдЧ рдЗрди рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реВрдВред рдореИрдВ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рдХреЛрдб рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛, рдФрд░ рдореИрдВ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд░рд┐рдПрдХреНрдЯрдлреНрд▓рдХреНрд╕ рдкрд░ рд░рд╣реВрдВрдЧрд╛ред

const AppConnector = createConnector((props$, state$, dispatch$, context$) => {
  // true when the user is logged in - drawn from Store state
  const loggedIn$ = state$
    .map(s => s.apiKey !== null)
    .distinctUntilChanged()

  // this returns an observable of a path to redirect to
  // in my app, I have a url like `/login?nextPath=dashboard`, but if that
  // isn't set, just go home
  const redirectTo$ = routeState$
    .map(s => s.router.query.nextPath || '/home')

  const redirect$ = loggedIn$
    .withLatestFrom(
      context$,
      redirectTo$,
      (loggedIn, context, path) => () => context.router.transitionTo(loggedIn ? path : '/login') // when the loggedIn state changes, i.e. user has logged in or out, respond to that change
    )
    .do(go => go())

  // It's awesome to have this here, because it means that no matter 
  // where the user loads in to the app (all child views of this view), 
  // the app will realise it needs to load data, and loads the according data 
  const userData$ = state$
    .map(getUser)

  const userDataIsEmpty$ = userData$
    .map(user => user.id === null || typeof user.id === 'undefined')
    .filter(s => s === true)

  const loadUserData$ = Rx.Observable.combineLatest(loggedIn$, userDataIsEmpty$, (logged, userDataIsEmpty) => loggedIn && userDataIsEmpty)
    // only when user is logged in but has no user data
    .filter(s => s === true)
    // fetch data with an action creator
    .withLatestFrom(dispatch$, (userData, dispatch) => () => dispatch(UserActions.loadUserData()))
    .forEach(go => go())


  return Rx.Observable.combineLatest(props$, state$, context$, redirect$, (props, state, context) => ({...props, ...state, ...context}))
}, render)

рдЖрдкрдХреЗ рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм @emmenko рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдореЗрдВ shouldRedirect рд╣реЛрдирд╛ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрд╡реЗрджрди рд╕реНрдерд┐рддрд┐ рдореЗрдВ errorMessage рд╣реЛрдирд╛ рдареАрдХ рд╣реИ, рдмрд╕ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдПрдХ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп errorMessage рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд▓реЙрдЧрд┐рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдВрддрд░реНрдЧрдд рд╣реИ, рдЬреИрд╕реЗ state.auth.errorMessage #$ ред

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

рдореИрдВ рд╕рд╣рдордд рд╣реВрдВред рдЪреАрдЬреЗрдВ рдЬреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЙрдкрдпреЛрдЧреА рд╣реЛрддреА рд╣реИрдВ рд╡реЗ рдЖрдИрдПрдордУ рд░рд╛рдЬреНрдп рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

рд╕рд╛рде рд╣реА, рд╕реНрд▓реИрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдореЗрдВ isLoggedIn рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╕рдВрдкрддреНрддрд┐ рд╣реИ, рдЬрд┐рд╕реЗ const isUserLoggedIn = state => state.user.id !== null рдЬреИрд╕реЗ рд╕рд╛рдзрд╛рд░рдг рдЪрдпрдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдЧрдгрдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред

рдЕрдзрд┐рдХ рдЪрдпрдирдХрд░реНрддрд╛ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП https://github.com/faassen/reselect рджреЗрдЦреЗрдВ

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП @frederickfogerty рдзрдиреНрдпрд╡рд╛рджред

рдкреНрд░рд╢реНрди рд╣рд╛рд▓рд╛рдВрдХрд┐: рдпрд╣ рд▓реЙрдЧрд┐рди рдХреЗ рд▓рд┐рдП рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЖрдорддреМрд░ рдкрд░ $#$ state $#$ рдореЗрдВ loggedIn рдзреНрд╡рдЬ рд╣реЛрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдиреНрдп рдкреГрд╖реНрдареЛрдВ рдЬреИрд╕реЗ рд╕рд╛рдЗрдирдЕрдк, рдкрд╛рд╕рд╡рд░реНрдб-рд░реАрд╕реЗрдЯ, рдЖрджрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
рд╡реЗ рдкреГрд╖реНрда рд▓реЙрдЧрд┐рди рдХреЗ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВ: рдареАрдХ рд╣реЛрдиреЗ рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВ, рдЕрдиреНрдпрдерд╛ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдПрдВред
рддреЛ рдЖрдк рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╣реИрдВрдбрд▓ рдХрд░рддреЗ рд╣реИрдВ? рдореИрдВ рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкреНрд░рд╡рд╛рд╣ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдХреЛ рдХрд╣рд╛рдБ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЪреАрдЬреЗрдВ рдЬреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЙрдкрдпреЛрдЧреА рд╣реЛрддреА рд╣реИрдВ рд╡реЗ рдЖрдИрдПрдордУ рд░рд╛рдЬреНрдп рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

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

рдЗрд╕ рддрд░рд╣ рдореИрдВ рд░рд╛рдЬреНрдп рдореЗрдВ рдХреБрдЫ рднреА рд╕реНрдЯреЛрд░ рдХрд┐рдП рдмрд┐рдирд╛ рдЗрд╕реЗ рдПрдЯреАрдПрдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

// actions
function login () {
  return { type: 'LOGGED_IN' }  
}

function submitLogin (form, dispatch) {
  return api.doLogin(form)
  .then(() => {
    dispatch(login()) // can dispatch something at this point
    return Promise.resolve()
  })
}

// in the component (login, signup, ...)
onSubmit () {
  actions.submitLogin(form, dispatch) // this returns a promise
  .then(() => this.setState({ shouldRedirect: true }))
  .catch(error => this.setState({ shouldRedirect: false, errorMessage: error }))
}

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдкрдХреЛ рдЖрд╡реЗрджрди рд╕реНрдерд┐рддрд┐ рдореЗрдВ isLoggedIn рдХрд╛ рднрдВрдбрд╛рд░рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╕рдВрдкрддреНрддрд┐ рд╣реИ

рд╣рд╛рдБ, рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

@gaearon рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рд╛рдорд╛рдиреНрдп рд╡рд░реНрдХрдлрд╝реНрд▓реЛ (рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдпрд╛ рд╢реЛ рдПрд░рд░) рдХреЗ рд▓рд┐рдП рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕реЗ "рд░реЗрдбрдХреНрд╕" рдпрд╛ рдХрд┐рд╕реА рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдХреНрдпрд╛ рд╣реЛрдЧрд╛?

рд╕рдВрдмрдВрдзрд┐рдд рдФрд░ рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдВ рдкрд┐рди рдХрд░реВрдВрдЧрд╛ ... рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореИрдВ рднреА рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдирд┐рдкрдЯ рд░рд╣рд╛ рдерд╛ рдФрд░ рд╡рд░реНрддрдорд╛рди рдореЗрдВ Redux рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЕрднреА рддрдХ рдХреБрдЫ рднреА рджрд┐рдЦрд╛рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЗрд╕реЗ рдЕрдкрдиреЗ рдЦрд╛рд▓реА рд╕рдордп рдореЗрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:
https://auth0.com/blog/2015/04/09/adding-authentication-to-your-react-flux-app/

рдпрд╣ рд╢реБрджреНрдз рдкреНрд░рд╡рд╛рд╣ рд╣реИ:
https://github.com/auth0/react-flux-jwt-authentication-sample

рд╢рд╛рдпрдж рдпрд╣ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИ ?!

@emmenko

рддреЛ рдЖрдк рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╣реИрдВрдбрд▓ рдХрд░рддреЗ рд╣реИрдВ?

рдЬрдм рддрдХ рдЖрдкрдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЙрдЧ рдЗрди рдХрд░ рд░рд╣рд╛ рд╣реИ, рддрдм рддрдХ isLoggedIn (рдЬреЛ рдРрдк рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдорд╛рдореВрд▓реА рд╣реИ) рдЕрднреА рднреА рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЙрдиреНрд╣реЗрдВ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдЧрд╛ред рдпрд╣ рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд╣ рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдХрд╣рд╛рдБ рд╕реЗ рдЖрдпрд╛ рд╣реИ :)

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

рдЗрд╕ рддрд░рд╣ рдореИрдВ рд░рд╛рдЬреНрдп рдореЗрдВ рдХреБрдЫ рднреА рд╕реНрдЯреЛрд░ рдХрд┐рдП рдмрд┐рдирд╛ рдЗрд╕реЗ рдПрдЯреАрдПрдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

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

componentWillReceiveProps(nextProps) {
  if (['/login', '/sign-up'].indexOf(this.props.router.path) !== -1 && this.props.isLoggedIn) {
    this.context.router.transitionTo(this.props.router.query.nextPath || '/home')
  }
}
  • рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рд▓реЙрдЧрд┐рди рд╕рдлрд▓ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдкреГрд╖реНрда рд╕реЗ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рд▓реЙрдЧрд┐рди рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рд▓реЙрдЧ рдЗрди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЙрд╕реА рдкреГрд╖реНрда рдкрд░ рд░рд╣рддрд╛ рд╣реИ (рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрддрд╛)

рдпрд╣ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрднреА рднреА рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рдореИрдВ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ/рддреНрд░реБрдЯрд┐ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реВрдВред

рдЖрдЗрдП рдПрдХ рдХрджрдо рдкреАрдЫреЗ рд╣рдЯреЗрдВ рдФрд░ рдХрд╣реЗрдВ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ reset-password рдкреГрд╖реНрда рд╣реИред рд╣рдо рдпрд╣ рднреА рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХреЗ рдПрдХ-рд╢реЙрдЯ рдЭрдВрдбреЗ (рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА рд░рд╛рдЬреНрдп рдХреЛ рдирд╣реАрдВ рдЫреВрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЬрдм рдореИрдВ рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдпрд╣реА рдореИрдВ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдкреНрд░рд╡рд╛рд╣ рдХреИрд╕рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХрд╣рд╛рдВ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдкреАрдПрд╕: рдЕрдм рддрдХ рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

[navigates to reset-password page] -> 
[types in email and hits submit] -> 
[onSubmit fires bound AC] ->
on successful reset this continues with:
[RESET_PASSWORD_SUCCESS] -> 
[resetPassword reducer returns state {passwordReset: true}] ->
[resetPasswordComponent.componentWillReceiveProps will check if state.passwordReset is true, and then will transition to its route]
on a failed reset this continues with:
[RESET_PASSWORD_FAILURE] -> 
[resetPassword reducer returns state {passwordResetError}] -> 
[resetPasswordComponent.componentWillReceiveProps() will check if state.passwordReset is true, and since is it not, nothing will happen - in render(), the error will be displayed]

рдпрд╣ рдХрд╣реАрдВ рднреА рд▓реЙрдЧрд┐рди рдФрд░ рд╕рд╛рдЗрди рдЕрдк рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдЙрддрдирд╛ рд╣реА рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рдпреБрдЧреНрдорд┐рдд рд╣реИ

рдореБрдЭреЗ рд╕реЛрдирд╛ рд╣реИ, рдореИрдВ рдХрд▓ рдХрд┐рд╕реА рдФрд░ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреВрдВрдЧрд╛

рдЗрд╕рд▓рд┐рдП рд╣рдо рд░рд╛рдЬреНрдп рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдЭрдВрдбреЗ рдЬрдорд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ;)

рдкреАрдПрд╕: рд╢реБрдн рд░рд╛рддреНрд░рд┐!

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд╡рд╛рд▓ рдереЛрдбрд╝рд╛ рдФрд░ рдЧрд╣рд░рд╛ рд╣реИ рддреЛ рдмрд╕ 'рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░реЗрдВ' рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ - рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд░рд╛рдЬреНрдп рдХреНрдпрд╛ рд╣реИ рдФрд░ рдХреМрди рд╕рд╛ рдбреЗрдЯрд╛ store рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХреМрди рд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╣реИред

рдореБрдЭреЗ рдлреНрд▓рдХреНрд╕ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЗ View рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╢реБрджреНрдз рдХрд╛рд░реНрдп render(state): DOM рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЛрдЪрдирд╛ рдкрд╕рдВрдж рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред
рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░рд▓ рд░реВрдк рдШрдЯрдХ рд▓реЗрддреЗ рд╣реИрдВ рдЬреЛ рджреЛ рдЗрдирдкреБрдЯ рдлрд╝реАрд▓реНрдб рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ:

class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
      </form>
    )
  }
}

рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рдЖрдВрддрд░рд┐рдХ рд╕реНрдерд┐рддрд┐ рд╕рдВрд╢реЛрдзрди рдХрд┐рдП рдЧрдП рддрд╛рдХрд┐ рдЕрдВрдд рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрдЧрд╛:

{
  name: 'John'
  surname: 'Snow'
}

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

рдЖрдЗрдП рдорд╛рди рд▓реЗрдВ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдкрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рдкреНрд░рдкрддреНрд░ рд╣реИред рдЕрдм рд╣рдореЗрдВ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рд╣рдо рдЗрд╕реЗ рдЕрдкрдиреА рд╡рд┐рд╢реЗрд╖ рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░реЗрдВрдЧреЗред

import { subscribe } from 'actions'

class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  onSubmit (event) {
    event.preventDefault()
    const { name, surname, email } = this.state
    subscribe(name, surname, email)
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
      </form>
    )
  }
}

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

  render () {
    //provided by connector of whatever
    const { props: { isLoading, error } } = this
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}
        disabled={isLoading}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
        {error ? <p>{ error }</p> : null}
      </form>
    )
  }

рд▓реЗрдХрд┐рди рдпрд╣рд╛рдБ рд╢реИрддрд╛рди рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ: рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдпрд╣ рдкреГрд╖реНрда рд╕реНрдерд┐рддрд┐ рдмрдиреА рд╣реБрдИ рд╣реИ рдФрд░ рдЕрдЧрд▓реА render(state) рдХреЙрд▓ рдПрдХ рдЧрдВрджреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдлреЙрд░реНрдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдлреЙрд░реНрдо рдорд╛рдЙрдВрдЯ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП cleanup рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореМрдЬреВрдж рдкреНрд░рддреНрдпреЗрдХ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рд╣рдо рд╕реНрдЯреЛрд░/рд░реЗрдбреНрдпреВрд╕рд░ рдХреЗ рд╕рд╛рде loading , submitted , failed рдФрд░ cleanup рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╣реА рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗтАж рдЙрд╕ рд░рд╛рдЬреНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд┐рд╕реЗ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ submitted рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдпрд╛ рдпрд╣ рдХреЗрд╡рд▓ рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рд╣реИ, рдЬреИрд╕реЗ name рдлрд╝реАрд▓реНрдб рдорд╛рдиред рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╢ рдореЗрдВ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдЬрдм рд╡рд╣ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рджреЗрдЦрддрд╛ рд╣реИ рддреЛ рд╡рд╣ рд╕рд╛рдл рдлреЙрд░реНрдо рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ? рдЙрддреНрддрд░: рдпрд╣ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред

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

рддреЛ рдХреИрд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдореЗрдВ рдШрдЯрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд╣реАрдВ рдФрд░ рдЗрд╕ рд░рд╛рдЬреНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ? рдЖрдЗрдП рдЗрд╕реЗ рдПрдХ рдмрд╛рд░ рдЖрдЬрд╝рдорд╛рдХрд░ рджреЗрдЦрддреЗ рд╣реИрдВред
рдЕрдзрд┐рдХ рдлреИрдВрд╕реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ 2015 рдореЗрдВ рд╣рдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд░рд╣рддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рд░ рдЬрдЧрд╣ Promises рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ Promise рд▓реМрдЯрд╛рдПрдВ:

function subscribe (name, surname, email) {
  return api.request('/subscribtions', 'create', { name, surname, email })
}

рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ Component рдореЗрдВ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

onSubmit (event) {
  event.preventDefault()
  const { name, surname, email } = this.state
  subscribe(name, surname, email)
    .then(() => { this.setState({ submitted: true }) })
    .catch(error => { this.setState({ error }) })
}

componentWillUpdate (object nextProps, object nextState) {
  if(nextState.submitted)
    redirect('somewhere')
}

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдШрдЯрдХ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдм рдХреБрдЫ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рд╛рдл рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИред
рддреЛ рд╣рдо рд▓рдЧрднрдЧ рд╡рд╣рд╛рдБ рд╣реИрдВред рдЕрдм рд╣рдо Component рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЪрд┐рдВрддрд╛рдУрдВ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдХрд╛рд░реНрд░рд╡рд╛рдИ рдФрд░ рд░рд╛рдЬреНрдп рдЕрджреНрдпрддрди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдирд╛:
(рд░реЗрдкреЛ рд╕реАрдорд╛ рдореЗрдВ рдмрдиреЗ рд░рд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ redux рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ)

import React, { PropTypes } from 'react'
import { bindActionCreators } from 'redux'

// Keeps track of action
export default function connectSubmitForm (Form, submitAction) {
  return React.createClass({
    contextTypes: {
      //redux Store
      store: PropTypes.object.isRequired
    },

    getInitialState () {
      return {}
    },

    onSubmit (...args) {
      const { context: { store: { dispatch } } } = this
      const { submitAction: submit }
        = bindActionCreators({ submitAction }, dispatch)
      submit(...args)
        .then(() => this.setState({ submitted: true }))
        .catch(error => this.setState({ error }))
    },

    render () {
      const {
        onSubmit,
        props,
        state: { submitted, error }
      } = this
      return (<Form {...props} onSubmit={onSubmit} submitted={submitted}
        error={error} />)
    }
  })
}

рддрдерд╛

// redirect to path if predicate returns true
export default function redirect (path, predicate) {
  return Component =>
    class Composed extends React.Component {

      componentWillMount () {
        if (predicate(props))
          redirectTo(path)
      }

      componentWillReceiveProps (nextProps) {
        if (predicate(nextProps))
          redirectTo(path)
      }

      render () {
        return <Component {...this.props} />
      }
    }
}

//redirect to path if submitted
export default function redirectSubmitted (path) {
  return redirect(path, ({ submitted }) => submitted)
}

рдЕрдм рдПрдХ рддрд░рдл рд╣рдорд╛рд░реЗ рдкрд╛рд╕ decorator рд╣реИ рдЬреЛ submitted рдФрд░ error рдкреНрд░реЛрдк рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ onSubmit рдХреЙрд▓рдмреИрдХ рдХреЗ рд╕рд╛рде рдФрд░ рджреВрд╕рд░реА рддрд░рдл decorator рдЬреЛ рдХрд╣реАрдВ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ рдЕрдЧрд░ рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ submitted === true ред рдЖрдЗрдП рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдлреЙрд░реНрдо рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИред

@redirectSubmitted('/')
class Form extends React.Component {

  onFieldChanged (event) {
    this.setState({[event.target.name]: event.target.value})
  }

  onSubmit (event) {
    event.preventDefault()
    const { name, surname, email } = this.state
    this.props.onSubmit(name, surname, email)
  }

  render () {
    return (
      <form onChange={::this.onFieldChanged} onSubmit={::this.onSubmit}>
        <input type="text" name="name" />
        <input type="text" name="surname" />
        <input type="email" name="email" />
        <button type="submit">Subscribe</button>
        {this.props.error ? <p>{ this.props.error }</p>: null}
      </form>
    )
  }
}

export default submitForm(Form, subscribe)

рдФрд░ рдпрд╣рд╛рдВ рдпрд╣ рд╣реИ: routing рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдХреЛрдИ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде рд╢реБрджреНрдз рд░реЗрдВрдбрд░ рдлреЙрд░реНрдо, flux рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдПрдкреНрд▓рд┐рдХреЗрд╢рди state , рдЬреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛: рд╕рдмрдорд┐рдЯ рдФрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВред

рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдФрд░ рдЕрдкрдирд╛ рд╕рдордп рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред

рдХрд╛рдлреА рдЙрдЪрд┐рдд! рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдЕрднреА рднреА Redux рдореЗрдВ рд╕реНрдерд╛рдиреАрдп рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ: # 159ред

@stremlenye рд╡рд╣ рдмрд╣реБрдд рдЪрд╛рд▓рд╛рдХ рд╣реИред рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП @iclanzan thx :)
рджрд░рдЕрд╕рд▓ рдЕрдм рдореИрдВ @gaearon рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдиреНрд╣реЛрдВрдиреЗ рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдерд╛ред рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рдЪрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП #159 рдЪрд░реНрдЪрд╛ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рд╕рдорд╛рдкрди - рдЬрдм рдЖрд░рдЖрд░ 1.0 рд╕рд╛рдордиреЗ рдЖрдПрдЧрд╛, рддреЛ рд╣рдо рдЗрд╕реЗ "рдпреВрд╕реЗрдЬ рд╡рд┐рдж рд░рд┐рдПрдХреНрдЯ рд░рд╛рдЙрдЯрд░" рд░реЗрд╕рд┐рдкреА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВрдЧреЗред
рдЗрд╕реЗ https://github.com/rackt/redux/issues/637 рдореЗрдВ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

@stremlenye рдЖрдкрдХрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ рд╣реИ! рдХреНрдпрд╛ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ - рдПрдХ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп - рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдЙрдЪреНрдЪ рдХреНрд░рдо рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╕рднреА _unathorized_ рдиреЗрд╕реНрдЯреЗрдб рд╣реЛрдВрдЧреЗ рдФрд░ рдПрдХ рдмрд╛рд░ рдЬрдм рд╕реНрдЯреЛрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛрдЧрд╛ рддреЛ рдпрд╣ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛?

<ReduxRouter>
    <Route component={ Auth }>
      <Route path="/" component={ Login } />
      <Route path="/reset-password" component={ ResetPassword } />
    </Route>
  </ReduxRouter>

рдХреБрдЫ рдЗрд╕ рддрд░рд╣, рдЬрд╣рд╛рдВ Auth рдХреЗрд╡рд▓ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдЦреНрдпрд╛рд▓ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЙрдЧ рдЗрди рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЗрд╕ рддрд░рд╣, рдореБрдЭреЗ рдЕрднреА рднреА Login рдШрдЯрдХ рд╕реЗ рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпрд╛рдВ рднреЗрдЬрдХрд░ рдЕрдкрдиреЗ рд╕реНрдЯреЛрд░ рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред рдЗрддрдирд╛ рд╢реБрджреНрдз рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдХрдо рдХреЛрдб рдФрд░ рдореЗрд░реЗ рд╕рд┐рд░ рдХреЛ рдкрд╛рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди :)

@tomazzaman рдзрдиреНрдпрд╡рд╛рдж :)
рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдЕрдзрд┐рдХрд╛рдВрд╢ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ ApplicationContainer рдЬреИрд╕реЗ рдХреБрдЫ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирдП Route рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд┐рдирд╛ рдЙрд╕реА рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк RR-v1.0.0-rc1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдк onEnter рд╣реБрдХ рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рд▓рдХреНрд╖реНрдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ: рдмрд╕ рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдкреНрд░рдорд╛рдгрд┐рдд рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ рдпрд╛ рдирд╣реАрдВред

рдореИрдВ рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЕрдкрдирд╛ рд╕рд┐рд░ рднреА рд▓рдкреЗрдЯ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @stremlenye рдиреЗ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдПрдХ "рд╕рдм рдХреБрдЫ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ - рд░реЗрдбреНрдпреВрд╕рд░ - рдЕрдкрдбреЗрдЯ-рдШрдЯрдХ-рд╕рд╛рде-рд╕реНрдЯреЛрд░-рд╕реНрдЯреЗрдЯ рд▓реВрдк" (рдореБрдЭреЗ рднреА) рдореЗрдВ рдлрдВрд╕ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рд╣рдо рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕реНрдЯреЛрд░ рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рд░рд╛рдЬреНрдп рдЬреЛ рдХреЗрд╡рд▓ рдРрдк рдореЗрдВ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (1 рд╕реНрдХреНрд░реАрди рдкрд░, рд╕рд╛рдорд╛рди рдЬреИрд╕реЗ "рдХреНрдпрд╛ рдореИрдВрдиреЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд░реАрд╕реЗрдЯ рдкрд╛рд╕рд╡рд░реНрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛"), рдЬрдмрдХрд┐ рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдПрд╕рд┐рдВрдХ рдХреЙрд▓ рдХрд░рдХреЗ рдФрд░ рдШрдЯрдХ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдХреЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп this.setState рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ + рдпрджрд┐ рд╣рдо рдЙрд╕ рдШрдЯрдХ рдХреЛ рджреВрд╕рд░реА рдмрд╛рд░ рдмрд╛рдж рдореЗрдВ рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЙрди рд╕рднреА рд░рд╛рдЬреНрдп рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕рднреА рд╢реБрд░реБрдЖрдд/рд╕рдлрд▓рддрд╛/рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдХреЛрдб рдХреЗ рд╕рд╛рде рд░рд╛рдЬреНрдп рд░реЗрдбреНрдпреВрд╕рд░ рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рднреА рдЬрд┐рдХреНрд░ рдирд╣реАрдВ рд╣реИред

рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИ, рдореЗрд░реЗ рдХреЛрдб рдХреЛ рдпрд╣рд╛рдВ рднреА рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдЧрд╛ред

@ рдЖрдИрдЖрд░-рдИрдВрдзрди рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕рдордп рд╣реЛрдЧрд╛ рддреЛ рдХреНрдпрд╛ рдЖрдк рдЬреАрдердм рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ?

рд╡реИрд╕реЗ рдРрд╕рд╛ рдХрд░рдирд╛ рдХрдард┐рди рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЬреЛ рдХрд┐рдпрд╛ рдЙрд╕рдХрд╛ рдореИрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЙрджрд╛рд╣рд░рдг рджреЗ рд╕рдХрддрд╛ рд╣реВрдВред рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдШрдЯрдХ рд╣реИ рдЬрд╣рд╛рдВ рдХреЛрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдирд╛ рдкрд╛рд╕рд╡рд░реНрдб рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░реАрд╕реЗрдЯ рдСрдкрд░реЗрд╢рди рдЕрдм рдЗрд╕ рддрд░рд╣ рд╣реЛрддрд╛ рд╣реИ:

  submitForgotPassword = (username) => {
    this.setState({isLoading:true})
    doForgotPassword(username).then((result) => {
      this.setState({passwordIsReset:true,isLoading:false})
    }).catch((result) => {
      this.setState({passwordIsReset:false,isLoading:false,errorMessage:result.error})
    })
  }

doForgotPassword рдПрдХ рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдореЗрд░реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдЬрд╛рдХреНрд╕ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред

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

рдФрд░ рд░реЗрдВрдбрд░ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ

  render() {

    let divClassName = ''

    if(this.state.isLoading) {
      divClassName = 'disable-controls'
    }

    let child = null

    if(this.state.passwordIsReset)
      child = (<ForgotPasswordSuccess/>)
    else
      child = (<ForgotPasswordForm submit={this.submitForgotPassword} errorMessage={this.state.errorMessage}/>)

    return (
      <div className={divClassName}>
        {child}
      </div>
    )
  }

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИред

рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ: +1:
рдПрдХрдорд╛рддреНрд░ рдЪрд╛рд▓ рдЬрд┐рд╕реЗ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдореЗрд░реЗ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рд╕реЗ) рдЙрдард╛рдИ рдЧрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╕реЗ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реИ (рдХреЗрд╡рд▓ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЛ рдкреНрд░реЙрдХреНрд╕реА рдХрд░реЗрдВ)ред рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ рд╣рдо рдШрдЯрдХ рджрд╛рдпрд░реЗ рдореЗрдВ Promise рд╕рд╛рдорд╛рди рдкрд░ рд╣реБрдХ рдЕрдк рдХрд░рдиреЗ рдХреЗ рдЕрд╡рд╕рд░ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╡рд╛рд╣ рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВрдЧреЗред

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

рд▓реЙрдЧ рдЗрди рдкреЗрдЬ рдкрд░ рдРрдк рд▓реЙрдЬрд┐рдХ рдРрдк рдЯреЙрдк рд╕реНрдЯреЗрдЯ рдХреЗ рдорд╛рд▓рд┐рдХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд╣реИ рдирд╛?

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

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

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдЗрд╕ рдХреНрд╖рдг рддрдХ рдХрд╛рдо рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдореИрдВ рдЕрдкрдиреА рднрд╡рд┐рд╖реНрдп рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд▓реЙрдЧрд┐рди-рдЪрд░рдг рдРрдк рд╕реНрдерд┐рддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдордЭреВрдВрдЧрд╛

рдЖрдк рдЕрдкрдиреЗ рд╕реНрдЯреЛрд░ рдХреЗ рдореВрд▓ рд╕реНрддрд░ рдкрд░ рдЕрдкрдиреЗ рд╕реНрдЯреЛрд░ рдХреЛ 'рдРрдк' рднрд╛рдЧ рдФрд░ 'рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛/рд▓реЙрдЧрд┐рди' рднрд╛рдЧ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд░реЗрдбреНрдпреВрд╕рд░ рдХреЗ рд╕рд╛рдеред рддреЛ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЖрдк рдЕрдкрдиреЗ рдРрдк рд░реЗрдбреНрдпреВрд╕рд░ рдХреЛ рд▓реЙрдЧрд┐рди рд░реЗрдбреНрдпреВрд╕рд░ рдХреЛрдб рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдХрднреА рднреА рдкреНрд░рджреВрд╖рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред

рд╕реЗ: рд╕реНрдХреЗрдЯрдлреНрд░реАрдХ < рд╕реВрдЪрдирд╛рдПрдВ @github.com рд╕реВрдЪрдирд╛рдПрдВ @github.com>
рдЙрддреНрддрд░-рдкреНрд░рддрд┐: рд░реИрдХреЗрдЯ/рд░реЗрдбрдХреНрд╕ <рдЙрддреНрддрд░@ reply.github.com [email protected] >
рджрд┐рдирд╛рдВрдХ: рд░рд╡рд┐рд╡рд╛рд░ 13 рджрд┐рд╕рдВрдмрд░ 2015 13:48
рдкреНрд░рддрд┐: рд░реИрдХреНрдЯ/рд░реЗрдбрдХреНрд╕ < [email protected] [email protected] >
рд╕реАрд╕реА: рдЬреЛрд░рд┐рд╕ рдореИрдиреНрд╕ < [email protected] [email protected] >
рд╡рд┐рд╖рдп: рдкреБрди: [рд░реЗрдбрдХреНрд╕] рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рд▓реЙрдЧрд┐рди/рд╕рд╛рдЗрдирдЕрдк рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдкрд░ рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ (#297)

@sompyl asarhttps://github.com/sompylasar рдореИрдВ рдПрдХ рдРрдк рд╕реНрдерд┐рддрд┐ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рд╣реВрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЬрдм рддрдХ рдЙрдкрдпреЛрдЧ рдореЗрд░реЗ рдРрдк рдХреЗ рдмрд╛рд╣рд░ рд╣реИ, рдореИрдВ рдЙрд╕реЗ рдПрдХ рд░реЗрдбрдХреНрд╕ рд╕реНрдЯреЛрд░ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╕рд░рд▓ рдРрдк рдХреА рд╕реЗрд╡рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЬреИрд╕реЗ рд╣реА рдЖрдк рдореЗрд░рд╛ рдРрдк рджрд░реНрдЬ рдХрд░реЗрдВрдЧреЗ рдореЗрд░рд╛ рд░реЗрдбрдХреНрд╕ рд╕реНрдЯреЛрд░ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдЗрд╕ рдХреНрд╖рдг рддрдХ рдХрд╛рдо рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдореИрдВ рдЕрдкрдиреА рднрд╡рд┐рд╖реНрдп рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд▓реЙрдЧрд┐рди-рдЪрд░рдг рдРрдк рд╕реНрдерд┐рддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдордЭреВрдВрдЧрд╛

рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ Gi tHubhttps: //github.com/rackt/redux/issues/297#issuecomment -164287194 рдкрд░ рджреЗрдЦреЗрдВред

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

рдореИрдВ рдлрд╛рдпрджреЗ рдирд╣реАрдВ рджреЗрдЦрддрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЪреАрдЬреЛрдВ рдХреЛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдФрд░ рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИред рдореИрдВ рдЕрдкрдиреЗ <Sign /> рдШрдЯрдХ рдкрд░ рдЕрдкрдиреА рдкреВрд░реНрд╡-рд▓реЙрдЧрд┐рди рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕рд╛рдЗрдирдЗрди, рд╕рд╛рдЗрдирдЕрдк рдФрд░ рдлреЙрд░рдЧреЙрдЯрдкрд╛рд╕рд╡рд░реНрдб рд╢рд╛рдорд┐рд▓ рд╣реИред

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

рд╕реЗ: рд╕реНрдХреЗрдЯрдлреНрд░реАрдХ < рд╕реВрдЪрдирд╛рдПрдВ @github.com рд╕реВрдЪрдирд╛рдПрдВ @github.com>
рдЙрддреНрддрд░-рдкреНрд░рддрд┐: рд░реИрдХреЗрдЯ/рд░реЗрдбрдХреНрд╕ <рдЙрддреНрддрд░@ reply.github.com [email protected] >
рджрд┐рдирд╛рдВрдХ: рд░рд╡рд┐рд╡рд╛рд░ 13 рджрд┐рд╕рдВрдмрд░ 2015 14:00
рдкреНрд░рддрд┐: рд░реИрдХреНрдЯ/рд░реЗрдбрдХреНрд╕ < [email protected] [email protected] >
рд╕реАрд╕реА: рдЬреЛрд░рд┐рд╕ рдореИрдиреНрд╕ < [email protected] [email protected] >
рд╡рд┐рд╖рдп: рдкреБрди: [рд░реЗрдбрдХреНрд╕] рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рд▓реЙрдЧрд┐рди/рд╕рд╛рдЗрдирдЕрдк рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдкрд░ рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ (#297)

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

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

рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ Gi tHubhttps: //github.com/rackt/redux/issues/297#issuecomment -164287893 рдкрд░ рджреЗрдЦреЗрдВред

рдореИрдВ рд╕рд╣рдордд рд╣реВрдВред
рд▓реЗрдХрд┐рди рдореИрдВ рд╕рд╛рдЗрдирдЕрдк рдХреЛ рдПрдХ рд░реВрдк рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ, рдПрдХ рд░рд╛рдЬреНрдп рдХреЗ рд╕рд╛рде - рдЬреЛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЪрд╛рд╣реЗ рдХрд┐рддрдирд╛ рднреА рдЬрдЯрд┐рд▓ рд╣реЛ ...

рджреВрд╕рд░реА рдУрд░, рдореБрдЭреЗ рд╕рд╛рдЗрди рдЕрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдкрддрд╛...
рд▓реЛрдЧ рдкрд╛рдЧрд▓ рд╣реИрдВ

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореИрдВ рдХреБрдЫ рд╕рдорд╛рди рд▓реЗрдХрд┐рди рдЕрд▓рдЧ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдорд┐рд▓рд╛ рд╣реВрдВред

рдореИрдВ рдПрдХ рд╕реБрдкрд░ рдХреЙрдореНрдкреНрд▓реЗрдХреНрд╕ рд╕рд╛рдЗрди рдЕрдк рдХреА рддрд░рд╣ рдкреНрд░рд╡рд╛рд╣ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдЬрд╛рд░реА рдкреГрд╖реНрда рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдирдкреБрдЯ рдХреЛ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рджреЗрддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдкреГрд╖реНрда рдПрдХ рдлреЙрд░реНрдо рд╣реИред рдкреНрд░рд╡рд╛рд╣ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдлреЙрд░реНрдордкреЗрдЬ_рдП -> рдлреЙрд░реНрдордкреЗрдЬ_рдмреА -> рдлреЙрд░реНрдордкреЗрдЬ_рд╕реА -> рд╕рдХреНрд╕реЗрд╕рдкреЗрдЬ

рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо FormPage_C рд╕реЗ рдкрд╣рд▓реЗ рдХреЛрдИ API рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдХреЗрд╡рд▓ FormPage_A/B рдкрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдбреЗрдЯрд╛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рдЙрди рд╕рднреА рдХреЛ FormPage_C рдореЗрдВ API рдХреЛ рднреЗрдЬрддреЗ рд╣реИрдВред

рддреЛ, рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдореЗрдВ рдлреЙрд░реНрдордкреЗрдЬ_рдП рдФрд░ рдлреЙрд░реНрдордкреЗрдЬ_рдмреА рдХреЗ рдлреЙрд░реНрдо рдбреЗрдЯрд╛ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдЯреЗрдЯ рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП?

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

рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреНрдпрд╛ рдЗрд╕реЗ рд▓рдЧрд╛рдиреЗ рдХрд╛ рд╕рд╣реА рд╕реНрдерд╛рди рд╣реИ? рдХреНрдпрд╛ рд╣рдореЗрдВ рдЗрд╕реЗ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд░реЗрдбрдХреНрд╕ рдлреНрд▓реЛ рд╕реЗ fake api рдЬреИрд╕реА рджреВрд╕рд░реА рдкрд░рдд рдмрдирд╛рдиреА рдЪрд╛рд╣рд┐рдП?

@frederickfogerty @gaearon @ir- food @stremlenye

рдореИрдВ рдХреЗрд╡рд▓ this.state рдореЗрдВ рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдЖрдкрдХреЗ рд╕рдмрдорд┐рдЯ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ рдЪрд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдк рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП FormPage_A.state рдХреЛ FormPage_B.props рдЖрджрд┐ рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ FormPage_C рдореЗрдВ рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВ

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

рдмрд╕ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЙрд╕ рдкреГрд╖реНрда рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

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

<Flow onForward={тАж} onBackward={}>
  <Step1 />
  <Step2 />
  <Step3 />
  тАж
  <Finish onSubmit={this.props.submit(this.state.model) />
</Flow>

@ir-рдИрдВрдзрди @stremlenye

рдЖрдкрдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╕рднреА рдЙрди рдЕрд╕реНрдерд╛рдпреА рдЪреАрдЬреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдзреЗ рдкреНрд░рд╡рд╛рд╣ рдореЗрдВ рдкреГрд╖реНрда рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рддрд╛ рд╣реИ

рдмрд╕ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЙрд╕ рдкреГрд╖реНрда рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

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

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

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

//fake api
const fakeApi = {
  getStepA: ()=>{
    /* get things from LS */
    return Promise
  },
  setStepA: ()=>{
    /* put things into LS */
    return Promise
  }
}

// action creator
submitA(dispatch, getState) { // thunk function
  fakeApi
    .setStepA()
    .then(dispatchSuccess)
    .then(transitionToStepB)
    .catch(dispatchError);
}

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

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

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

рдФрд░ рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдордзреНрдп-рд╕рд╛рдЗрдирдЕрдк рдкреБрдирдГ рд▓реЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдмрд╕ рдЗрди рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдореВрд▓ рдШрдЯрдХ рдХреЛ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ localStorage рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВред

@kpaxqin рдореИрдВ "рдирдХрд▓реА рдПрдкреАрдЖрдИ" рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдЬрд╛рдКрдВрдЧрд╛ред рдирдХрд▓реА рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ рдХреНрдпреЛрдВ, рдпрд╣ рд╕рд┐рд░реНрдл рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рд╕реНрдЯреЛрд░реЗрдЬ рдПрдкреАрдЖрдИ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреА рдмрд╣реБ-рдЪрд░рдгреАрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЪрд╛рд╣рд┐рдПред рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдПрдкреАрдЖрдИ рд╕рд░реНрд╡рд░ рдкрд░ рд╣реЛ рдФрд░ HTTP рдпрд╛ рдЕрдиреНрдп рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛред

рдореИрдВ @ ir-рдИрдВрдзрди рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рд╕рднреА рдмрд╣реБ-рдЪрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рди рдХрд┐ рдХреЗрд╡рд▓ рд╡рд░реНрддрдорд╛рди рдЪрд░рдгред

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

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

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

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

рдпрд╣ рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ "рдЗрд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдпрд╛ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ", рдпрд╣ "рдХреНрдпрд╛ рдореИрдВ рдЕрдкрдиреЗ рдореВрд▓ рдШрдЯрдХ рд╡рд░реНрдЧ рдореЗрдВ рдЗрд╕ 'рддрджрд░реНрде' рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реВрдВ" рдмрдирд╛рдо "рдХреНрдпрд╛ рдореИрдВ рдкреВрд░реА рдХреНрд░рд┐рдпрд╛/рд░реЗрдбреНрдпреВрд╕рд░/рд░рд╛рдЬреНрдп рдиреГрддреНрдп рдХрд░рддрд╛ рд╣реВрдВ"ред
рдЕрдЧрд░ рдпрд╣ рдЕрд╕реНрдерд╛рдпреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рд╣реИ рддреЛ рдореБрдЭреЗ рдПрдХреНрд╢рди/рд░реЗрдбреНрдпреВрд╕рд░ рд╕реЗ рдЧреБрдЬрд░рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реВрдВред

@ рдЖрдИрдЖрд░-рдИрдВрдзрди: +1:

@stremlenye рдХреГрдкрдпрд╛ рдореЗрд░рд╛ рдЙрддреНрддрд░ рджреЛрдмрд╛рд░рд╛ рдкрдврд╝реЗрдВред рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдкрдХреЛ рджреГрдврд╝рддрд╛ API рдкрд░рдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб API рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

@ ir-рдИрдВрдзрди рдХреНрд░рд┐рдпрд╛рдУрдВ рд╕реЗ рдирд╣реАрдВ рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИ/рд░реЗрдбреНрдпреВрд╕рд░ рд░рд╛рдЬреНрдп рдХреЗ рд╕рдВрдХреНрд░рдордгреЛрдВ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдФрд░ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдпрддрд╛ рдХреЛ рд░рджреНрдж рдХрд░ рджреЗрддрд╛ рд╣реИред

@ рдЖрдИрдЖрд░-рдИрдВрдзрди рдлреЙрд░реНрдо рдЬрдорд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдкрдиреА рдРрдк рд╕реНрдерд┐рддрд┐ рд╕рд╛рдлрд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ "рдкреНрд░рджреВрд╖рд┐рдд" рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

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

@sompylasar рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдХреЛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рдмрдЯрди рдХреЗ рд╕рд╛рде рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ - рдЕрдирд╣реЗрд▓реНрдб рд╡рд┐рдлрд▓рддрд╛рдУрдВ рдХреЗ рдмрд╛рдж рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ: рдпрд╣ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдирд╛ рдХрдард┐рди рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдХрд┐рд╕ рддрд░рд╣ рд╕реЗ рджреВрд╖рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рд░рдгрдиреАрддрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

@stremlenye рд╣рд╛рдБ, рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрднреА-рдХрднреА рдХрдард┐рди рд╣реЛрддреА рд╣реИред рдЕрдиреБрдорд╛рдирд┐рдд рд░рд╛рдЬреНрдп рдФрд░ рд╕рдВрдХреНрд░рдордг рдЗрд╕реЗ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреЗ рд╣реИрдВред

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

рдореЗрд░реЗ рд▓рд┐рдП Immutable.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ redux рдХреЗ рд╕рд╛рде рдХреБрдЫ рдмрдирд╛рдирд╛ рдмрд╕ рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЖрдк Signup рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рд╛рдЗрди рдЕрдк рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рд╕рдорд╕реНрдпрд╛ рдЕрдзрд┐рдХ рдореМрд▓рд┐рдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рд╡реЗрдмрдПрдк рдореЗрдВ рдРрд╕реЗ рдмрд╣реБрдд рд╕реЗ рдорд╛рдорд▓реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣реА рдкрд░реЗрд╢рд╛рди рдХрд░рддрд╛ рд╣реИ рдореБрдЭреЗред

@ir-рдИрдВрдзрди

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

рдореЗрд░реЗ рд▓рд┐рдП Immutable.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ redux рдХреЗ рд╕рд╛рде рдХреБрдЫ рдмрдирд╛рдирд╛ рдмрд╕ рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред

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

рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕рд╛рдЗрдирдЕрдк рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рд╛рдЗрди рдЕрдк рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП

рд╣рд╛рдБ, рдореЗрд░реЗ рдорди рдореЗрдВ рдпрд╣реА рдерд╛ред

рд▓реЗрдХрд┐рди рд╕рдорд╕реНрдпрд╛ рдЕрдзрд┐рдХ рдореМрд▓рд┐рдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рд╡реЗрдмрдкреИрдк рдореЗрдВ рдЖрдкрдХреЗ рдмрд╣реБрдд рд╕реЗ рдорд╛рдорд▓реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣реА рдореБрдЭреЗ рдкрд░реЗрд╢рд╛рди рдХрд░рддрд╛ рд╣реИред

рдЗрд╕реЗ рд╣реА рд╣рдо рд╕реНрдкрд╖реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдХрд╣рддреЗ рд╣реИрдВ -- рд╣рд░ рдкрд▓ рдореЗрдВ рд╣рдо рдРрдк рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдХрдИ рдШрдЯрдХ рд╣реЛрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рд░рд╛рдЬреНрдп рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдХрдо рд╕реНрдкрд╖реНрдЯ рдФрд░ рдЕрдзрд┐рдХ рдЧрддрд┐рд╢реАрд▓ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ https://github.com/tonyhb/redux-ui рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░реЗрдВ

рдЬреЗрдПрд╕ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рде рдпрд╣реА рдкреВрд░реА рд╕рдорд╕реНрдпрд╛ рд╣реИред "рдЪрд▓реЛ рд╕рдореНрдореЗрд▓рдиреЛрдВ рд╕реЗ рдЪрд┐рдкрдХреЗ рд░рд╣реЗрдВ"ред рдФрд░ рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд▓реЛрдЧреЛрдВ рдХреЛ рдпрд╣ рдПрд╣рд╕рд╛рд╕ рд╣реЛрдиреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬрдЯрд┐рд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд▓реЛрдЧ рдЧрд▓рддрд┐рдпрд╛рдБ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдЗрдореНрдпреВрдЯреЗрдмрд▓.рдЬреЗрдПрд╕ рдЬреИрд╕реЗ рд╕рдорд╛рдзрд╛рди рд▓реЗрдХрд░ рдЖрддреЗ рд╣реИрдВред

рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХреНрдпреЛрдВ рд╣реЛрдЧрд╛? рдпрджрд┐ рдЖрдк 'рд░рд┐рдХреЙрд░реНрдб' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЖрдк рдЙрди рд╕рднреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рдЬрдм рддрдХ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдкрдврд╝ рд░рд╣реЗ рд╣реИрдВ) рд╕рд╛рдорд╛рдиреНрдп рдЬреЗрдПрд╕ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЧреБрдгреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдбреЙрдЯ рдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде, рдПрдХ рд▓рд╛рдн рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдк рд╕рд╛рдордиреЗ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреМрди рд╕реЗ рдЧреБрдг рдЖрдкрдХреА рд╡рд╕реНрддреБ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИрдВ .

рдореИрдВ рдЕрдкрдиреЗ рд╕рднреА redux рд╡рд┐рдХрд╛рд╕ Immutable.js рдХреЗ рд╕рд╛рде рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЛ рдЧрд▓рддреА рд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд░реЗрдбрдХреНрд╕ рдореЗрдВ рдПрдХ рдмрдбрд╝рд╛ рдлрд╛рдпрджрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА 'рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛' рднреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

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

@ir-рдИрдВрдзрди
рдореЗрд░реЗ рд▓рд┐рдП рдЪреАрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдиреАрдп рд╕реНрдЯреЛрд░реЗрдЬ рдореЗрдВ рд░рдЦрдирд╛ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдШрдЯрдХ рдореЗрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИред

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

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдирдХрд▓реА рдПрдкреАрдЖрдИ рдХрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рдЙрди рдЪреАрдЬреЛрдВ рдХреЛ only need in a few screens рдХреЛ redux рдХреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ред рдлреЙрд░реНрдордкреЗрдЬ_рдП/рдмреА рдореЗрдВ рд╡реЗ рдлреЙрд░реНрдо рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рд░реНрдл рдПрдкреАрдЖрдИ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рдЕрдЧрд▓реЗ рдЪрд░рдг рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ:

//action
submitFormA (formA) {
  fakeApi
    .saveFormA(formA)
    .then(()=>{ transitionTo(nextPage) })
    .catch()
}

рдФрд░ рдлреЙрд░реНрдордкреЗрдЬ_рд╕реА (рдЕрдВрддрд┐рдо рдлреЙрд░реНрдо) рдореЗрдВ:

submitFormC (formC) {
  fakeApi
    .getFormAnB()
    .then(mergeFormData(formC)) //mergeFormData is a curry function
    .then(realApi.submitSignUp)
    .catch()
}

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

@sompylasar рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдХреЛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рдмрдЯрди рдХреЗ рд╕рд╛рде рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ - рдЕрдирд╣реЗрд▓реНрдб рд╡рд┐рдлрд▓рддрд╛рдУрдВ рдХреЗ рдмрд╛рдж рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ: рдпрд╣ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдирд╛ рдХрдард┐рди рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдХрд┐рд╕ рддрд░рд╣ рд╕реЗ рджреВрд╖рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рд░рдгрдиреАрддрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

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

рдФрд░ рд░рд╛рдЬреНрдп рдХреЛ рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд░рдЦрдиреЗ рд╕реЗ рдЪреАрдЬреЗрдВ рдЬрдЯрд┐рд▓ рд╣реЛрдиреЗ рдкрд░ рддрд░реНрдХ рдХрд░рдирд╛ рдХрдард┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдирдХрд▓реА рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рд╣рдо рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдмрджрд▓рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рдЕрдзрд┐рдХ рдЕрдиреБрдорд╛рдирд┐рдд рд▓рдЧрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдХрдо рдЬрдЯрд┐рд▓рддрд╛ рд╡рд╛рд▓реЗ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдирдХрд▓реА рдПрдкреАрдЖрдИ рдмрд╣реБрдд рднрд╛рд░реА рд▓рдЧрддреА рд╣реИред

рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рд╕реЗ рдирд╣реАрдВ рдЧреБрдЬрд░рд╛ред рдпрд╣рд╛рдВ рдореИрдВ рд╕рд┐рд░реНрдл рдЕрдкрдирд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рджреЗрддрд╛ рд╣реВрдВ: рдХрдВрдкреЛрдиреЗрдВрдЯрд╡рд┐рд▓ рд░рд┐рд╕реАрд╡рдкреНрд░реЙрдкреНрд╕ рдореЗрдВ рдкреНрд░реЛрдк рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВред

рдХрд╣реЗрдВ рдХрд┐ рд░рд╛рдЬреНрдп рдХрд╛ рдЖрдХрд╛рд░ рд╣реИ: {loginPending, loginError}, рд▓реЙрдЧрд┐рди рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп, loginPending = true рд╕реЗрдЯ рдХрд░реЗрдВред рд╕рдлрд▓ рдпрд╛ рдЕрд╕рдлрд▓ рд╣реЛрдиреЗ рдкрд░, {loginPending: false, loginError: 'some error.' рд╕реЗрдЯ рдХрд░реЗрдВред }.

рддрдм рдореИрдВ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдХрд┐рд╕реА рдШрдЯрдХ рдореЗрдВ рд▓реЙрдЧрд┐рди рд╕рдлрд▓рддрд╛ рдШрдЯрдирд╛ рд╣реИ рдФрд░ рдкреГрд╖реНрда рдХреЛ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВ:

componentWillReceiveProps(nextProps) {
  if (this.props.loginPending && !nextProps.loginPending && !nextProps.loginError) {
    // Login success, redirect the page here.
  }
}

рдпрд╣ рд╕рд┐рд░реНрдл рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╕реБрдВрджрд░ рдирд╣реАрдВ рд╣реИред

react-router-redux рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рдкрд░ рдлрд╝реЙрд░реНрдо рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рдиреЗ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдореЗрд░рд╛ рд╡рд┐рдирдореНрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред рд░реЗрдбреНрдпреВрд╕рд░:

const initialState = {
    login: initialLoginState,
    signup: initialSignupState,
    // ...
};


export default function(state = initialState, action) {
  switch (action.type) {
    case '@@router/LOCATION_CHANGE':
      return {
        ...state,
        login: initialLoginState,
        signup: initialSignupState
      };
      // ...

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рддрд░реАрдХрд╛ рдареАрдХ рд╣реИ? рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реВрдВред рдмрддрд╛рдПрдВ рдХрд┐ рдЖрдк рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ:

рд░реЗрдбрдХреНрд╕ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ:

import { checkStatus } from 'helpers/fetch_helpers';
import { AUTH } from 'config/constants.endpoints';
import { USER_LOGGED_IN, USER_LOGGED_OUT, USER_REGISTERED } from 'config/constants.actions';
import { replace } from 'react-router-redux';

// other actions...

const userRegistered = (user) => ({
  type: USER_REGISTERED,
  user
});

export const register = (formData, redirectTo = '/') => {
  const fetchParams = {
    method: 'post',
    body: formData
  };

  const handleData = (dispatch) => (response) => response.json().then( (data) => {
    dispatch(userRegistered(data));
    dispatch(replace(redirectTo));
  });

  return (dispatch) => fetch(AUTH, fetchParams)
    .then(checkStatus)
    .then(handleData(dispatch));
};

рд░рдЬрд┐рд╕реНрдЯрд░ рдлреЙрд░реНрдо рдХрдВрдЯреЗрдирд░:

import React, { Component } from 'react';
import RegisterForm from './register_form';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as userActions from 'store/actions/user';
import { parseFormErrors } from 'helpers/fetch_helpers';

class RegisterFormContainer extends Component {
  state = {
    errors: {}
  }

  async handleSubmit(e) {
    e.preventDefault();

    const form = e.currentTarget;
    const formData = new FormData(form);
    const { register } = this.props.actions;

    try {
      await register(formData);
    } catch (error) {
      const errors = await parseFormErrors(error);

      this.setState({ errors });
    }
  }

  render() {
    return (
      <RegisterForm handleSubmit={ ::this.handleSubmit } errors={ this.state.errors } />
    );
  }
}

const mapDispatchToProps = (dispatch, ownProps) => ({
  actions: bindActionCreators({ register: userActions.register }, dispatch)
});

export default connect(
  null,
  mapDispatchToProps
)(RegisterFormContainer);

рдФрд░ рд╕рд╣рд╛рдпрдХ:

export const checkStatus = (response) => {
  if (response.ok) {
    return response;
  } else {
    const error = new Error(response.statusText);

    error.response = response;
    throw error;
  }
};

export const parseFormErrors = (error) => error.response.json().then( (data) => {
  if (data.errors) {
    const joinedErrors = _.mapValues(data.errors, (errors) => errors.join(' ') );

    return { ...joinedErrors };
  } else {
    console.error('request failed:', error);

    return {};
  }
});

рдХреНрдпрд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ - рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЗрд╡рд▓ рд╕рдлрд▓ рдкрдВрдЬреАрдХрд░рдг Redux рд╕реНрдЯреЛрд░ рдореЗрдВ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рддреНрд░реБрдЯрд┐ рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЪрд▓реА рдЬрд╛рддреА рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓ рд░рд╣реА рд╣реИ, рдлрд┐рд░ рджреВрд╕рд░реЗ рдкреГрд╖реНрда рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдлрд┐рд░ рд╕реЗ рдлреЙрд░реНрдо рдкреЗрдЬ рдкрд░ рдЬрд╛рддрд╛ рд╣реИ - рдлреЙрд░реНрдо рдЦрд╛рд▓реА рд╣реИ рдФрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИред рдХреЛрдИ "USER_REGISTRATION_REQUEST" рдпрд╛ "USER_REGISTRATION_FAILURE" рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕реНрдерд┐рддрд┐ рдирд╣реАрдВред

@sunstorymvp

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

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓ рд░рд╣реА рд╣реИ, рдлрд┐рд░ рджреВрд╕рд░реЗ рдкреГрд╖реНрда рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдлрд┐рд░ рд╕реЗ рдлреЙрд░реНрдо рдкреЗрдЬ рдкрд░ рдЬрд╛рддрд╛ рд╣реИ - рдлреЙрд░реНрдо рдЦрд╛рд▓реА рд╣реИ рдФрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИред

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

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдЖрдкрдиреЗ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ async/рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рд╢рд░реНрдХрд░рд╛ рджрд┐рдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЪреАрдиреА рдЗрд╕ рддрдереНрдп рдХреЛ рдЫреБрдкрд╛рддреА рд╣реИ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рддреАрди рд░рд╛рдЬреНрдп рд╣реИрдВ (рдкрд╣рд▓реЗ, рдкреНрд░рдЧрддрд┐ рдкрд░, рдмрд╛рдж рдореЗрдВ)

рдЗрд╕ рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рджрд┐рдП рдмрд┐рдирд╛ рдХрд┐ рдореИрдВ рдПрд╕рд┐рдВрдХ/рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдпрд╛ рдирд╣реАрдВ, рдпреЗ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдореМрдЬреВрдж рд╣реИрдВред

рд╡реНрдпреВ рдХрдВрдкреЛрдиреЗрдВрдЯ рдореЗрдВ рдЫреБрдк рдЬрд╛рддреЗ рд╣реИрдВ рдпреЗ рд╕реНрдЯреЗрдЯреНрд╕

рдЬреИрд╕рд╛ рдХрд┐ рдЗрд░рд╛рджрд╛ рд╣реИ, рд╡рд╣ рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рд╣реИ .. рдпрд╣ рдРрдк рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХреНрдпреЛрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рд░рдВрдн рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рдЪрд╛рд▓реВ...

рдФрд░ рдЕрдиреБрд░реЛрдз рддреНрд░реБрдЯрд┐ рджреГрд╢реНрдп рдореЗрдВ рдирд┐рдпрдВрддреНрд░рд┐рдд рд╣реЛ рдЬрд╛рддреА рд╣реИ рдФрд░ redux рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ

рдЬреИрд╕рд╛ рд╕реЛрдЪрд╛ рд╡реИрд╕рд╛

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

рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдШрдЯрдХ рд░рд╛рдЬреНрдп рдпрд╛ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдиреБрд░реЛрдз рд╕рдлрд▓ рд╣реЛрдЧрд╛, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХреГрдд рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред register рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░ (рд╣реИрдВрдбрд▓рдбреЗрдЯрд╛) рджреЗрдЦреЗрдВред

рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рдХреНрд░рд┐рдпрд╛ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ ...

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

рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдШрдЯрдХ рд░рд╛рдЬреНрдп рдпрд╛ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдиреБрд░реЛрдз рд╕рдлрд▓ рд╣реЛрдЧрд╛, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХреГрдд рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд░рдЬрд┐рд╕реНрдЯрд░ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░ (рд╣реИрдВрдбрд▓рдбрд╛рдЯрд╛) рджреЗрдЦреЗрдВред

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

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

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

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрддреНрдпрдзрд┐рдХ рд╣рдардзрд░реНрдорд┐рддрд╛ рди рдХрд░реЗрдВред Redux рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕рд╛рдорд╛рди рдбрд╛рд▓рдиреЗ рдХреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХрд╛рд░рдг рд╣реИрдВ, рдФрд░ рдЖрдкрдХреЗ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдерд╛рдиреАрдп рдШрдЯрдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХреБрдЫ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХрд╛рд░рдг рд╣реИрдВред http://redux.js.org/docs/FAQ.html#organizing -state-only-redux-state рдФрд░ https://news.ycombinator.com/item?id=11890229 рджреЗрдЦреЗрдВред

рдареАрдХ рд╣реИ, рдЕрдм рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╣реИ: рдпрд╣ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдзрдиреНрдпрд╡рд╛рдж!

рдореИрдВ componentWillReceiveProps рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдореЗрд░реЗ рдШрдЯрдХ рдкрд░ auth рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИред рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдорджрдж рдХрд░рддрд╛ рд╣реИред

// using reduxform
class LoginForm extends Component {
  static propTypes = {
    // this holds info on the current user.
    auth: PropTypes.shape({
      userId: PropTypes.number,
      token: PropTypes.string
    }),
     // react-router-redux.
    history: PropTypes.object.isRequired,
    submitting: PropTypes.bool.isRequired,
    fields: PropTypes.object.isRequired
  };
  componentWillReceiveProps(newProps) {
    const { auth } = newProps;
    auth && auth.token && this.props.history.go('#/');
  }
  render() {
    return (/**...*/) // form logic here.
  }
}

рдХреНрдпрд╛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рдЧрд▓рдд рд╣реИ?

рдРрд╕реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ http://codereview.stackexchange.com/questions/138296/implementing-redirect-in-redux-middleware?
рдорд┐рдбрд▓рд╡реЗрдпрд░ рдореЗрдВ react-router-redux push рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдпреВрдЖрд░рдПрд▓ рдкрд╛рд╕ рдХрд░рдирд╛ рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрд▓рд┐рдВрдЧ next рд╡рд┐рдзрд┐ред

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