路线变化的反应开放模式

时间:2017-05-08 22:43:56

标签: reactjs react-router react-redux redux-form semantic-ui-react

我正在构建一个带有登录模式的React / Redux应用程序,该模式应在用户导航到/user/signin时打开。在页面组件加载之前,调度操作以将isModalOpen设置为true 模态组件使用connect将模态状态映射到props。但是,当页面加载时,模态组件似乎在更新父页面组件的分派之前接收模态状态。 我已经尝试将isModalOpen作为道具从页面组件传递下来,当我导航到路线时,它正确显示模态。除非我通过模态组件调度动作以将isModalOpen设置为false并关闭模态,否则父组件上的props不会更新,因此模态保持关闭状态。

以下是我正在使用的代码:

用户登录页面组件

class UserSignInPage extends React.Component {
  componentWillMount() {
    this.props.openModal()
  }

  componentWillUnMount() {
    this.props.closeModal()
  }

  render() {
    const { location, isModalOpen } = this.props
    return (
      <StackedMenuTemplate header={<Header />} menu={<Navigation />} footer={<Footer />}>
        <Overview />
        <SignInForm redirectTo={location.query.redirect} isModalOpen />
      </StackedMenuTemplate>
    )
  }
}

UserSignIn.propTypes = {
  isModalOpen: PropTypes.bool,
  location: PropTypes.object,
  openModal: PropTypes.func.isRequired,
  closeModal: PropTypes.func.isRequired,
}

const mapStateToProps = (state) => ({
  isModalOpen: isOpen(state, 'LOGIN'),
})

const mapDispatchToProps = (dispatch) => ({
  openModal: () => {
    dispatch(modalShow('LOGIN'))
  },
  closeModal: () => {
    dispatch(modalHide('LOGIN'))
  },
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(UserSignIn)

用户登录模态容器

const handleSubmit = (values, dispatch) => {

})

const mapStateToProps = (state) => ({
  isAuthenticated: state.auth.isSignedIn,
  isModalOpen: isOpen(state, 'LOGIN'),
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  handleLogout: () => {
    dispatch(logout())
  },
  handleRedirect: () => {
    dispatch(push(ownProps.redirectTo || '/'))
  },
  handleModalClose: () => {
    dispatch(modalHide('LOGIN'))
  },
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(
  reduxForm({
    form: 'UserSignIn',
    onSubmit: handleSubmit,
  })(Form)
)

用户登录表单组件

class UserSignInForm extends Component {
  componentWillMount() {
    this.props.handleLogout()
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.isAuthenticated && nextProps.isAuthenticated) { // true after successful submit
      this.props.handleRedirect()
    }
  }

  shouldComponentUpdate(nextProps) {
    if (this.props.isModalOpen === nextProps.isModalOpen) {
      return false
    }
  }

  render() {
    const { handleSubmit, isModalOpen, handleModalClose } = this.props

    return (
      <Modal open={isModalOpen} onClose={handleModalClose} closeIcon='close'>
        <Modal.Header content='Sign In' />
        <Form onSubmit={handleSubmit}>
          <Modal.Content>
            <Form.Field>
              <label>Email</label>
              <Field name='email' component={Input} type='email' />
            </Form.Field>
            <Form.Field>
              <label>Password</label>
              <Field name='password' component={Input} type='password' />
            </Form.Field>
          </Modal.Content>
          <Modal.Actions>
            <Button type='submit'>
            Sign In
          </Button>
          </Modal.Actions>
          <div>
            <Link to='/user/forgot-password' >
              Forgot Password?
            </Link>
          </div>
        </Form>
      </Modal>
    )
  }
}

UserSignInForm.propTypes = {
  isModalOpen: PropTypes.bool,
  handleModalClose: PropTypes.func.isRequired,
  isAuthenticated: PropTypes.bool.isRequired,
  handleLogout: PropTypes.func.isRequired,
  handleRedirect: PropTypes.func.isRequired,
  handleSubmit: PropTypes.func.isRequired,
}

export default UserSignInForm

1 个答案:

答案 0 :(得分:0)

我最终解决了这个问题。我从选择器中错误地得到了状态。

糟糕!