0

Safari Desktop and Mobile

I've been racking my brain for the past couple days and can't seem to figure this issue out.

What is happening

When clicking on a button it greys out and becomes disabled. It then redirects a user completely to a different URL but when the user clicks back to the previous page, it still has the button greyed out from previous action.

What should happen

When clicking on a button it greys out and becomes disabled. It then redirects a user completely to a different URL but when the user clicks back to the previous page, it should reset the page state so that the buttons are now clickable again.

Has anybody come across this issue before?

Example code of state management:

/** 
REDUCER
**/

const boilerDetailsStateObject = {
    fetchingBoilerDetails: true,
    compareId: false,
    Package: false,
    calendarDates: false,
    financeCalculator: {
        price: 0,
        term: 0,
        terms: null,
        deposit: 0,
        Package: null,
        selectedAPR: null,
        selectedYear: 0
    },
    selectingBoiler: false,
    selectedDate: false
};

const reducer = (state = boilerDetailsStateObject, action) => {
    switch(action.type) {
        case "SHOWALLCALENDARDATES":
        case "PICKBOILER":
            if (action.skipCustomise) {
                let heatableQuote = boilerStoreObject;
                heatableQuote.Input.InstallDate = state.selectedDate;

                setCookie({
                    cname: 'heatable-quote', cvalue: heatableQuote, exdays: 2
                });
            }
      
      // Changes url
      location.href = `/boiler/${action.compareId}/${response.id}`;

            return state;

        case "PICKBOILERLOADING":
            return {
                ...state,
                ...{
                    selectingBoiler: action.stop ? false : true
                }
            }

        default:
            return state;
    }
};

export const BoilerDetailsStore = createStore(reducer);


/** PARENT WITH PROVIDER **/

class BoilerDetails extends Component {
  constructor (props) {
    super(props);
  }

  render () {
    return (
      <Provider store={BoilerDetailsStore}>
        <BoilerDetailsContainer />
      </Provider>
    );
  }
}

export default BoilerDetails;


/** MAP PROPS FOR COMPONENT **/
const mapStateToProps = (state) => {
    return {
        fetchingBoilerDetails: state.fetchingBoilerDetails,
        compareId: state.compareId,
        Package: state.Package,
        calendarDates: state.calendarDates,
        financeCalculator: state.financeCalculator,
        selectedDate: state.selectedDate,
        selectingBoiler: state.selectingBoiler
    };
}

export { mapStateToProps };

/** COMPONENT **/

import React, {Component} from 'react';
import {connect} from 'react-redux';
import { mapStateToProps } from '../../shared/BoilerDetailsMapState';

class ShowAllCalendarDates extends Component {
    constructor (props) {
        super(props);
    }

    selectBoiler = () => {
        this.props.dispatch({type: 'PICKBOILERLOADING'});

        this.props.dispatch({
            type: 'PICKBOILER',
            compareId: this.props.compareId,
            packageReference: this.props.Package.PackageReference,
            skipCustomise: true,
            dispatch: this.props.dispatch
        });
    }

    render () {
        return (
            <>
                <p className="small mx-auto d-block w-100 text-center">
                    <i className="fal fa-calendar-alt"></i>
                    <a href="#" 
            className={`${this.props.selectingBoiler ? 'disabled' : ''}`} 
            onClick={this.selectBoiler}>See all available dates</a>
                </p>
            </>
        );
    }
}

export default connect(mapStateToProps)(ShowAllCalendarDates);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Quick Solution to fix: (Is there a better way?)

/**
 * If browser back button was used, flush cache
 * This ensures that user will always see an accurate, up-to-date view based on their state
 * https://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked
 */
(function () {
  window.onpageshow = function(event) {
    if (event.persisted) {
      window.location.reload();
    }
  };
})();
YaBCK
  • 2,949
  • 4
  • 32
  • 61
  • Can you provide the code for it ? – Bhaskar Joshi Jun 08 '21 at 08:48
  • @BhaskarJoshi - I've shown little extract from the code, hopefully this is enough for you... It happens when the user press back button on the actual browser – YaBCK Jun 08 '21 at 08:56
  • are you updating the value in the store when you click on button ? – Shyam Jun 08 '21 at 09:34
  • @Shyam Yes the button get disabled based on state.. it's within the `selectBoiler` function and then it get dispatched to the reducer to update state. – YaBCK Jun 08 '21 at 09:37
  • just have an component level state for disabling the button instead of having it in the redux store . – Shyam Jun 08 '21 at 09:40
  • @Shyam I thought about that but there was few factors of the redux store which make the decision of the button becoming renabled e.g. if request to change url fails etc so needs to update state within the redux based on the dispatch actions. – YaBCK Jun 08 '21 at 09:48

0 Answers0