1

I am working on a forgot password form. When the user fills in the form - I want to replace the form with a thank you message, then redirect the user to the login page after 5 seconds. I also want to empty the forgotData state - so that a user can return back to the form - or refresh etc.. to fill it in again..

my current code looks like this - I've tried to null the state on componentWillUnmount - but its not working.

<Redirect refresh='5' to='/login' >

^ is something like that possible?

the forgot page looks like this.

import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchForget } from '../../actions/forgotAction';

import { Row, Col } from 'antd';

// components
import ForgotPasswordSyncValidationForm from './ForgotPasswordSyncValidationForm'

// this is a class because it needs state
class ForgotPassword extends Component {

  constructor(props, context) {
    super(props, context);
    this.submit = this.submit.bind(this);
  }

  componentDidMount() {    
    // console.log('this', this)
  }

  componentWillMount () {
    document.body.classList.add('screenbackground');
  }

  componentWillUnmount() {
    document.body.classList.remove('screenbackground');

    this.state = {
      forgotData: null
    }
  }

  submit(data) {
    this.props.fetchForget(data);
  }

  render() {

    // when the user has applied for a new password
    /*
    if(this.props.forgotData.isForgot){
      setTimeout(function() { 
        return <Redirect to='/login'/>;
      }.bind(this), 5000);
    }
    console.log(this.props.forgotData)
    */

    return (
      <div className="Page form-components dark">
        <h2>Forgot Password?</h2>        
        <Row>
          <Col xs={24} sm={24} md={10}>
            <p>A message here about what this forgot form is about</p>
          </Col>
          <Col xs={24} sm={24} md={24}>
              <Row>
                <Col xs={24} sm={24} md={6}>
                  {!this.props.forgotData.isForgot ? (
                     <ForgotPasswordSyncValidationForm onSubmit={this.submit} />
                  ) : (
                    <div>
                    <p>Thank you for filling in the forgot password form. We have generated a new password for you, please check your email.</p>
                      <Redirect to='/login'/>
                    </div>
                  )}
                </Col>
              </Row>
          </Col>
        </Row>
        <div className="shell" />
        <div className="screen-background forgot" />        
      </div>
    )
  }

}

function mapStateToProps(state) {
  return {
    forgotData: state.forgot
  };
}

function mapDispatchToProps(dispatch) {
 return bindActionCreators({ fetchForget }, dispatch);
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ForgotPassword))
The Old County
  • 89
  • 13
  • 59
  • 129
  • useful? May need to create a logout state -- https://stackoverflow.com/questions/35622588/how-to-reset-the-state-of-a-redux-store – The Old County Sep 08 '17 at 16:41
  • 1
    https://stackoverflow.com/questions/43230194/how-to-use-redirect-in-the-new-react-router-dom-of-reactjs – The Old County Sep 08 '17 at 17:00
  • What is the difference between the current behavior and the desired behavior. – ruby_newbie Sep 08 '17 at 18:01
  • A) Filling in the form it pops up the welcome message, but then doesn't redirect to the login page after a few seconds. B) On being redirected to the login page clicking to another page, and then coming back - it still has the data so you are still left on the thank you part. So I am unsure how to flush the data on leaving the page, – The Old County Sep 08 '17 at 18:41

2 Answers2

0
componentWillUnmount() {
    document.body.classList.remove('screenbackground');

    this.state = {
      forgotData: null
    }
}

Your problem is that you are setting the local state.

function mapStateToProps(state) {
  return {
    forgotData: state.forgot
  };
}

On mount, your redux state will get mapped to your local. So unless you specifically reset your redux state back to null, you will keep getting the same value after the first submit. Redux state does not reset unless manually reset or page refresh.

Geno Diaz
  • 400
  • 1
  • 7
  • 21
0

Ok how is this? So when you go to a different page or refresh -- the forgot page unmounts -- and in doing so clears the forgotData state.. -- but how about the delay in redirecting etc..

the action // forgotAction.js

import axios from 'axios';

export const FETCH_FORGOT_SUCCESS = 'FETCH_FORGOT_SUCCESS'
export const FETCH_FORGOT_FAILURE = 'FETCH_FORGOT_FAILURE'
export const FETCH_FORGOT_CLEAR = 'FETCH_FORGOT_CLEAR'

export function forgotSuccess(response) {
  return {
    type: FETCH_FORGOT_SUCCESS,
    payload: response
  }
}

export function forgotFail(response) {
  return {
    type: FETCH_FORGOT_FAILURE,
    payload: response
  }
}

export function forgotClear() {
  return {
    type: FETCH_FORGOT_CLEAR,
    payload: null
  }
}


export function fetchForget(data) {
  let url = 'https://api.github.com/users/theoldcounty';
  return function (dispatch) {     
    axios.get(url)
      .then(function (response) {
        //console.log(response);
        dispatch(forgotSuccess(response));
      })
      .catch(function (error) {
        //console.log(error);
        dispatch(forgotFail(error));
      });
  }
}

//forgotReducer.js

import { FETCH_FORGOT_SUCCESS, FETCH_FORGOT_FAILURE, FETCH_FORGOT_CLEAR } from '../actions/forgotAction'

export function forgotReducer (state = {}, action) {
  //console.log('reducer FORGOT act', action)
  switch (action.type) {
    case FETCH_FORGOT_SUCCESS:
      return {...state, data: action.payload, isForgot: true};
    case FETCH_FORGOT_FAILURE:
      return {...state, data: action.payload, isForgot: false}; 
    case FETCH_FORGOT_CLEAR:
      return {...state, data: action.payload, isForgot: false}; 
    default:
      return {...state} 
  }
}

the form // ForgotPassword.js

import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchForget, forgotClear } from '../../actions/forgotAction';

import { Row, Col } from 'antd';

// components
import ForgotPasswordSyncValidationForm from './ForgotPasswordSyncValidationForm'

// this is a class because it needs state
class ForgotPassword extends Component {

  constructor(props, context) {
    super(props, context);
    this.submit = this.submit.bind(this);
  }

  componentDidMount() {    
    // console.log('this', this)
  }

  componentWillMount () {
    document.body.classList.add('screenbackground');
  }

  componentWillUnmount() {
    document.body.classList.remove('screenbackground');

    console.log("CLEAR MY FORGOT STATE", this);
    this.props.forgotClear();
  }

  submit(data) {
    this.props.fetchForget(data);
  }

  render() {

    // when the user has applied for a new password
    /*
    if(this.props.forgotData.isForgot){

    }
    console.log(this.props.forgotData)
    */

    return (
      <div className="Page form-components dark">
        <h2>Forgot Password?</h2>        
        <Row>
          <Col xs={24} sm={24} md={10}>
            <p>A message here about what this forgot form is about</p>
          </Col>
          <Col xs={24} sm={24} md={24}>
              <Row>
                <Col xs={24} sm={24} md={6}>
                  {!this.props.forgotData.isForgot ? (
                     <ForgotPasswordSyncValidationForm onSubmit={this.submit} />
                  ) : (
                    <div>
                      <p>Thank you for filling in the forgot password form. We have generated a new password for you, please check your email.</p>
                      {/*<Redirect to='/login'/>*/}
                    </div>
                  )}
                </Col>
              </Row>
          </Col>
        </Row>
        <div className="shell" />
        <div className="screen-background forgot" />        
      </div>
    )
  }

}

function mapStateToProps(state) {
  return {
    forgotData: state.forgot
  };
}

function mapDispatchToProps(dispatch) {
 return bindActionCreators({ fetchForget, forgotClear }, dispatch);
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ForgotPassword))
The Old County
  • 89
  • 13
  • 59
  • 129