React 監聽頁面是否切出,避免多餘請求

不知道你是否是跟我同樣,遇到過下面這種狀況:瀏覽器

頁面須要定時發送請求,獲取數據,並且這個請求是一個公共請求,應用中全部頁面都會進行這樣一個操做。因此假如用戶打開五個頁面,那五個頁面都會發送請求,即使用戶看不到其他的4個。這種多餘的請求會加劇服務端的壓力。bash

瀏覽器裏在當前標籤頁切換時,會觸發 visibilitychange 事件,咱們能夠經過監聽這個事件來解決咱們的問題。async

class AgentList extends React.Component {
    constructor(props) {
        super(props);
        this.state= {
            list: []
        }
        this.refresher = this.createRefresher(this.getNotice, 30 * 1000);
    }
    
    componentDidMount() {
        window.setTimeout(() => {
          this.getNotice();
        }, 6000);

        document.addEventListener('visibilitychange', this.handleVisibilitychange);
    }
    
    componentWillUnmount() {
        this.refresher.stop();
        document.removeEventListener('visibilitychange', this.handleVisibilitychange);
    }
    
    getNotice = async () => {
        if (!document.hidden) {
          this.refresher.start();
        }
    
        const { data } = await API.getNotice();
        if (data && data.status === '1') {
            const { list } = data;
            this.setState({ popupList });
        }
    }
    
    handleVisibilitychange = () => {
        if (document.hidden) {
            this.refresher.stop();
        } else {
            window.setTimeout(() => {
                this.getNotice();
            }, 6000);
        }
    });
    
    createRefresher = (f, delay) => {
        let timer = null;
        const start = () => {
            if (timer === undefined) {
                timer = setInterval(f, delay);
            } else {
                clearInterval(timer);
                timer = undefined;
                timer = setInterval(f, delay);
            }
        };

        const stop = () => {
            if (timer) {
                clearInterval(timer);
                timer = undefined;
            }
        };

        return { start, stop };
    }
    
    render () {
        const { list } = this.state;
        return (
            <ul>
                list.map(item => <li>item</li>)
            </ul>
        )
    }
}
複製代碼

頁面中不是必要的請求,能夠延遲發送,儘可能減小頁面進入時同時發送的請求:ui

window.setTimeout(() => {
    this.getNotice();
}, 6000);
複製代碼

監聽 visibilitychange 事件,當頁面切出時,清除定時器;當頁面切入時,從新發送請求,並在 getNotice() 當中判斷若是頁面在展現中,則開啓定時器。this

handleVisibilitychange = () => {
    if (document.hidden) {
        this.refresher.stop();
    } else {
        window.setTimeout(() => {
            this.getNotice();
        }, 6000);
    }
});
複製代碼

在這記錄下,若是有錯誤的地方,歡迎你們批評之爭,哈哈哈哈spa

相關文章
相關標籤/搜索