简体   繁体   中英

How do i make my reusable react component saves when the user clicks button?

My component this.props.save(); when componentWillUnmount ? however if i leave the page to an external link in a different tab it does not trigger componentWillUnmount

my component

 export default class AutoSave extends React.Component { constructor(props) { super(props); this.setIntervalId = null; } componentDidMount() { if (!window.onbeforeunload) { window.onbeforeunload = () => { this.props.save(); }; } this.setIntervalId = setInterval(() => this.props.save(), this.props.intervalInMs); } componentWillUnmount() { this.props.save(); clearInterval(this.setIntervalId); } render() { return <span className="saving">Last saved at {now()}</span>; } } 

My link looks like this

<Link href="http://www.google.com"  target="_blank">
      Google Link
    </Link> 

How can I make component save when user clicks link? It's a react/redux app.

Why are you doing some kind of job in a class that extends from "React.Component". In ReactJS Component is not meant for to do jobs like that. From official documentation "Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.".There is no part in your component except the span that is related to ui. Anyway you should create AutoSave as Pure Component and use it in all React Components. :

export default class AutoSave 
{
  constructor(saveFn, intervalInMs) {
    this.saveFn = saveFn;
    this.setIntervalId = setInterval(
        () => { 
            this.save();
        }, 
        intervalInMs
    );
  }

  unmount() {
    this.save();
    clearInterval(this.setIntervalId);
  }

  save() {
    this.saveFn();
    this.callOnSaveCallback();
  }

  onSave(callback) {
    this.onSaveCallback = callback;
  }

  // private method that calls onSaveCallback
  callOnSaveCallback() {
    if(this.onSaveCallback != null)
        this.onSaveCallback();
  }

}

And use it in my React Components like this :

import AutoSave from './AutoSave';
export default class ReactComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            // ... other properties
            "lastSave": new Date()
        }
        this.save = this.save.bind(this);
        this.autoSave = new AutoSave(this.save, 100);
        this.autoSave.onSave(
            () => {
                this.setState(
                    {
                        "lastSave": new Date()
                    }
                );
            } 
        )
    }

    componentWillUnmount() {
        this.autoSave.unmount();
        this.autoSave = null;
    }  

    onClick() {
        this.autoSave.save();
    } 

    save() {
        // some saving job
    }

    render() {
        return ( 
            <div>
                // ... other components
                <Link href="http://www.google.com"  target="_blank" onClick={this.onClick.bind(this)}>
                  Google Link
                </Link> 
                <span className="saving">Last saved at {this.state.lastSave}</span>
            </div>
        );
    } 
}

Opening a new tab will not trigger componentWillUnmount() nor onbeforeunload. In both cases because your app is still open in the original tab. React does not unmount components immediately before you close or navigate away from the page, so componentWillUnmount() would do nothing even if the page were to close. onbeforeunload only triggers when you navigate away from the page in the same tab, or close the tab/window.

If you want to reliably call this.props.save() every time the user clicks your button, then simply add an onClick handler to the button.

render() {
  return <span onClick={this.props.save} className="saving">Last saved at {now()}</span>;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM