Reputation: 93
My intention is to update the 'isEditorFocused' state whenever the focused element changed, and if the div contains the focused element, deliver true into the Editor component.
However, the code does not work as my intention... It updates state only the first two times.
This is my Code. Actually not the exact code, but it is the core part of my question. If there is any typo, please ignore it. I checked it all in my real code file.
export default AddArticle = () => {
const [isEditorFocused, setIsEditorFocused] = React.useState(false);
const editorRef = React.useRef(null);
React.useEffect(() => {
if(editorRef.current !== null) {
if(editorRef.current.contains(document.activeElement)
setIsEditorFocused(true);
else
setIsEditorFocused(false);
}
}, [document.activeElement]}
return (
<div ref={editorRef} tabIndex="0">
<Editor isEditorFocused={isEditorFocused}></Editor>
<FileUploader {some props}/>
</div>
)
}
Upvotes: 0
Views: 5855
Reputation:
try this way.
const AddArticle = () => {
const [isEditorFocused, setIsEditorFocused] = React.useState(false);
const handleBlur = (e) => {
setIsEditorFocused(false)
};
handleFocus = (){
const currentTarget = e.currentTarget;
if (!currentTarget.contains(document.activeElement)) {
setIsEditorFocused(true);
}
}
return (
<div onBlur={handleBlur} onFocus={handleFocus}>
<Editor isEditorFocused={isEditorFocused}></Editor>
</div>
);
};
Upvotes: 0
Reputation: 13452
Not to completely change your code, but couldn't you just use onFocus
and onBlur
handlers?
For example:
const AddArticle = () => {
const [isEditorFocused, setIsEditorFocused] = React.useState(false);
return (
<div
onFocus={() => {
setIsEditorFocused(true);
}}
onBlur={() => {
setIsEditorFocused(false);
}}
tabIndex="0"
>
<Editor isEditorFocused={isEditorFocused}></Editor>
</div>
);
};
Working codepen
As T J mentions so eloquently, your issue is with document.activeElement
Note regarding React's current support for onFocus
vs onFocusIn
:
React uses onFocus and onBlur instead of onFocusIn and onFocusOut. All React events are normalized to bubble, so onFocusIn and onFocusOut are not needed/supported by React.
Source: React Github
Upvotes: 1
Reputation: 43166
The main problem is this: [document.activeElement]
.
The useEffect
dependency array only works with React state, and document.activeElement
is not React state.
You can try using a focusin event listener on your <div>
, if it receives the event it means itself or something inside it got focus, since focusin
event bubbles as long as nothing inside is explicitly preventing propagation of this event.
Upvotes: 0