Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

95
Views
Manage child component visibility by parent focus in React

I have a search input component in React, which also has a lot of options. I want the options box to appear when the input is focused, or while there's interaction in the box. This box should disappear when something outside of either search input of the box is being focused. So, it behaves like a pretty standard behavior.

There is a problem that I'm not sure how to solve. Some of the actions inside the options box cause another component to be rendered inside the box, so the focus is being lost (the browser focuses the <body>). My component thinks that it means to hide the options box.

I found a fix for that - I only hide the box if the blur of the container was caused by something from outside of it. It works correctly in some cases. But there's a problem when, let's say, there's a button causing the options box to render something else, making the button itself disappear. The focus goes to the <body> and I can no longer hide the options box without manually focusing on the search input and then focusing out.

Are there some techniques to manage visibility per real or pseudo focus? In perfect scenario, I'd like to avoid programatically focusing my element in, for two reasons:

  1. I'd like the autofocus attribute to work correctly.
  2. There are really a lot of components in a tree for the options box - making them all focus back programatically would mean a lot of repetitive code.

For simplicity, I removed the props and elements irrelevant to the question. But there's quite a bit going on for the <OptionsBox />.

Here's my simplified component:

import { useState } from 'react';
import OptionsBox from './OptionsBox';

export default function Search() {
    const [value, setValue] = useState('');
    const [showOptions, setShowOptions] = useState(false);

    return (
        <div
            tabIndex={-1}
            onFocus={() => setShowOptions(true)}
            onBlur={event => {
                const isChildFocused = event.currentTarget.contains(event.relatedTarget);

                if (!isChildFocused) {
                    setShowOptions(false);
                }
            }}
        >
            <input
                type="text"
                value={value}
                onChange={event => setValue(event.target.value)}
            />
            {showOptions && (
                <OptionsBox />
            )}
        </div>
    );
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I tried to get some workaround to work on this issue and find it this way (in the link).

  • Autofocus parent wrapper (depends on requirement).
  • track the click event. If it is inside, then keep the focus else, blur the <OptionBox />

Here is the change that I have done
  • Added ref to parentDiv and passed it to <OptionBox/> for tracking
  • Added 2 buttons for testing onClick focus events
    • 1st onCLick for focusing body
    • 2nd onClick to focus input within <Parent/> / <OptionBox/>
  • I added a clickHandler to check, if the element you are trying to focus on is within parentDiv, if so, then keep the focus else blur it and setState to false.

Not sure about the Efficiency of this solution but you can try this (if already haven't tried it) as it totally depends on the use case.

Link: https://codesandbox.io/s/youthful-hypatia-4mu2x?file=/src/OptionBox.js

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!