Reputation:
It seems like history.pushState is not working in Chrome on iOS when executed manually without any touch/click interaction.
I need help with understanding why iOS Chrome does this, and if possible, how to fix it.
https://codepen.io/grymer/pen/OOmebv
Here is a codepen with a minimum working example. To test it, you need to fork the pen and go into debug view in Chrome on an iOS device.
Then you will see "a button that says "To B". Press it and then use browser back. You will see that this behavior differs from any other browser.
var React, { Component } = React;
var { BrowserRouter, Redirect, Route, Switch } = ReactRouterDOM;
class App extends Component {
render() {
return (
<BrowserRouter basename={location.href}>
<Switch>
<Route path="/b" component={B} />
<Route component={A} />
</Switch>
</BrowserRouter>
);
}
}
class A extends Component {
constructor() {
super();
this.state = {};
this.handleClick = this.handleClick.bind(this);
}
render() {
if(this.state.redirect) {
return <Redirect push to="/b" />
}
return (
<div>
On page A
<button onClick={this.handleClick}>To B</button>
</div>
);
}
handleClick() {
this.setState({ redirect: true });
}
}
class B extends Component {
constructor() {
super();
this.state = {
showModal: false
};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
this.button.click(); // comment this line to manually open the modal by tapping the button
}
render() {
return (
<div>
On page B
{ this.state.showModal ? <Modal history={this.props.history} onClose={() => this.setState({ showModal: false }) } /> : null }
<button ref={(el) => this.button = el } onClick={this.handleClick}>Open modal</button>
</div>
);
}
handleClick() {
this.setState({
showModal: true
});
}
}
class Modal extends Component {
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
this.onPopState = this.onPopState.bind(this);
}
componentDidMount() {
this.props.history.push(this.props.history.location.pathname, { type: 'modal' });
window.addEventListener('popstate', this.onPopState);
}
componentWillUnmount() {
window.removeEventListener('popstate', this.onPopState);
}
render() {
return (
<div>
Modal is opened
<button onClick={this.handleClick}>Close modal</button>
</div>
);
}
handleClick() {
this.props.onClose();
this.props.history.goBack();
}
onPopState() {
this.props.onClose();
}
}
ReactDOM.render(<App />, document.getElementById('react-container'));
Upvotes: 1
Views: 2596
Reputation:
Chromium team has acknowledged and they are working on a fix.
https://bugs.chromium.org/p/chromium/issues/detail?id=783382#c3
Upvotes: 2