브라우저 탭의 포커스가 React에 있는지 확인합니다.JS
리액트JS에 웹사이트가 있어요탭이 포커스가 맞거나 숨겨질 때마다 콜백을 받고 싶다.Page Visibility API를 발견했는데 ReactJS에서 사용하는 방법을 알 수 없습니다.
콜백을 등록하는 라이프 사이클 방법은 무엇입니까?
React 16.8에서 후크를 사용하여 구축했습니다.
import React, { useEffect } from "react";
// User has switched back to the tab
const onFocus = () => {
console.log("Tab is in focus");
};
// User has switched away from the tab (AKA tab is hidden)
const onBlur = () => {
console.log("Tab is blurred");
};
const WindowFocusHandler = () => {
useEffect(() => {
window.addEventListener("focus", onFocus);
window.addEventListener("blur", onBlur);
// Calls onFocus when the window first loads
onFocus();
// Specify how to clean up after this effect:
return () => {
window.removeEventListener("focus", onFocus);
window.removeEventListener("blur", onBlur);
};
}, []);
return <></>;
};
export default WindowFocusHandler;
이 조작은 유효합니다.
componentDidMount() {
window.addEventListener("focus", this.onFocus)
}
componentWillUnmount() {
window.removeEventListener("focus", this.onFocus)
}
onFocus = () => {
//
}
편집: "blur"도 마찬가지이며 탭이 숨겨질 때 작동합니다.
@Assaf의 회답에서 훅을 사용한 사용을 확인합니다.
확인할 수 있는 신뢰할 수 있는 방법이 없기 때문에 몇 가지 방법을 조합할 필요가 있습니다.리액트 훅의 콘텍스트를 다음에 나타냅니다.
import React, { useState, useEffect } from 'react'
export const WindowContext = React.createContext(null)
export const WindowContextProvider = props => {
const [windowIsActive, setWindowIsActive] = useState(true)
function handleActivity(forcedFlag) {
if (typeof forcedFlag === 'boolean') {
return forcedFlag ? setWindowIsActive(true) : setWindowIsActive(false)
}
return document.hidden ? setWindowIsActive(false) : setWindowIsActive(true)
}
useEffect(() => {
const handleActivityFalse = () => handleActivity(false)
const handleActivityTrue = () => handleActivity(true)
document.addEventListener('visibilitychange', handleActivity)
document.addEventListener('blur', handleActivityFalse)
window.addEventListener('blur', handleActivityFalse)
window.addEventListener('focus', handleActivityTrue )
document.addEventListener('focus', handleActivityTrue)
return () => {
window.removeEventListener('blur', handleActivity)
document.removeEventListener('blur', handleActivityFalse)
window.removeEventListener('focus', handleActivityFalse)
document.removeEventListener('focus', handleActivityTrue )
document.removeEventListener('visibilitychange', handleActivityTrue )
}
}, [])
return <WindowContext.Provider value={{ windowIsActive }}>{props.children}</WindowContext.Provider>
}
당신의 문제를 해결하는 방법은 다음과 같습니다.
import React from 'react';
import PageVisibility from 'react-page-visibility';
class YourComponent extends React.Component {
state = {
isWindowInFocus: true,
}
componentDidMount() {
const { isWindowInFocus } = this.props;
if (!isWindowInFocus) {
// do something
}
}
listentoWindow = isVisible => {
this.setState({
isWindowInFocus: isVisible,
});
}
render() {
return (
<PageVisibility onChange={this.listentoWindow}>
<div>
Your component JSX
</div>
</PageVisibility>
);
}
}
사용자가 탭 사이를 전환하는지, 태스크바에서 아이콘을 더블 클릭하여 브라우저를 최소화할 수 있는지 여부를 감지하는 방법 등 필요한 기능을 모두 제대로 하지 못했습니다.
여러 번 작업을 중단했지만 올바른 상태를 관리하거나 태스크바 아이콘에서 최소화할 때 작동하지 않거나 여러 작업을 계속 수행할 수 없었습니다.
포커스가 바뀔 때마다 서버를 요청해야 했기 때문에 위의 상황은 조금 '아니오'였습니다.
그래서 제가 한 일은 이렇습니다.
const DetectChatFocus = () => {
const [chatFocus, setChatFocus] = useState(true);
useEffect(() => {
const handleActivityFalse = () => {
setChatFocus(false);
serverRequest(false);
};
const handleActivityTrue = () => {
setChatFocus(true);
serverRequest(true);
};
window.addEventListener('focus', handleActivityTrue);
window.addEventListener('blur', handleActivityFalse);
return () => {
window.removeEventListener('focus', handleActivityTrue);
window.removeEventListener('blur', handleActivityFalse);
};
}, [chatFocus]);
};
export default DetectChatFocus;
현재 이 기능은 Chrome과 Firefox 모두에서 매우 잘 동작하고 있습니다.주요 컴포넌트 또는 필요한 장소에서 초기화하기만 하면 됩니다.이 모든 시나리오에서 윈도 포커스를 추적하여 동작당1개의 서버만 요구합니다.
최신 후크:
import { useCallback, useEffect, useState } from "react";
const useTabActive = () => {
const [visibilityState, setVisibilityState] = useState(true);
const handleVisibilityChange = useCallback(() => {
setVisibilityState(document.visibilityState === 'visible');
}, []);
useEffect(() => {
document.addEventListener("visibilitychange", handleVisibilityChange)
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange)
}
}, []);
return visibilityState;
}
export default useTabActive;
Document.visibilityState 사용
보다 완전하고 최적화된 후크:
import React, { useState, useEffect } from 'react'
import _ from 'lodash'
export default function useIsWindowFocused(): boolean {
const [windowIsActive, setWindowIsActive] = useState(true)
const handleActivity = React.useCallback(
_.debounce(
(e: { type: string }) => {
if (e?.type == 'focus') {
return setWindowIsActive(true)
}
if (e?.type == 'blur') {
return setWindowIsActive(false)
}
if (e?.type == 'visibilitychange') {
if (document.hidden) {
return setWindowIsActive(false)
} else {
return setWindowIsActive(true)
}
}
},
100,
{ leading: false },
),
[],
)
useEffect(() => {
document.addEventListener('visibilitychange', handleActivity)
document.addEventListener('blur', handleActivity)
window.addEventListener('blur', handleActivity)
window.addEventListener('focus', handleActivity)
document.addEventListener('focus', handleActivity)
return () => {
window.removeEventListener('blur', handleActivity)
document.removeEventListener('blur', handleActivity)
window.removeEventListener('focus', handleActivity)
document.removeEventListener('focus', handleActivity)
document.removeEventListener('visibilitychange', handleActivity)
}
}, [])
return windowIsActive
}
직접 상태를 보는 것이 더 간단하다고 생각합니다.document.visibilityState, 다시 돌아오기 때문에'visible'또는'hidden':
const [visibilityState, setVisibilityState] = useState('visible')
useEffect(() => {
setVisibilityState(document.visibilityState)
}, [document.visibilityState])
언급URL : https://stackoverflow.com/questions/49902883/check-if-the-browser-tab-is-in-focus-in-reactjs
'source' 카테고리의 다른 글
| 리액트 훅 - 후드 아래에서 무슨 일이 일어나고 있습니까? (0) | 2023.02.15 |
|---|---|
| jQuery: txt 파일을 로드하여 div에 삽입합니다. (0) | 2023.02.11 |
| Angular에서 뷰와 모델 사이의 값을 변환할 수 있습니까?입력용 JS? (0) | 2023.02.11 |
| Rest Assured의 JsonPath를 통해 익명 어레이 요소 액세스 (0) | 2023.02.11 |
| Angular의 http 데이터와 유사한 정적 데이터에서 관찰 가능을 생성하는 방법은 무엇입니까? (0) | 2023.02.11 |