Search code examples
javascriptreactjsformstextboxcomponents

How to clear an autocomplete textbox component when dropdown component onChange selection occurs in React


I have a React app with 2 separate components in a parent component: a dropdown component ( SearchDropdown) and an autocomplete textbox component (Autocomplete).

 <div className="sidebar" style={{
      borderLeft: "1px solid gray"
 }}>
     <h2 style={{ textAlign: "center", color: "grey" }}>Filter By:</h2>
     <hr style={{ color: "grey", marginBottom: "20px" }} />
     <form onSubmit={(e) => {
         e.preventDefault();
         const { state } = autoCompleteRef.current;
         const keys = searchDropdownRef.current.state.userInput;
         callSearchAPI(state.userInput, keys);
     }}>
         <SearchDropdown ref={searchDropdownRef}
             onSearchDropdownChange={listHandler}
         />
         <hr style={{ color: "grey", marginBottom: "20px" }} />
         <label style={{ color: "grey" }}>Enter Value</label> <br />
         <Autocomplete ref={autoCompleteRef}
             suggestions={autoData}
             style={{ marginBottom: "10px" }} />
         <button className="btn btn-primary" > Search</button>
     </form>
 </div >

I have a modest goal here. Whenever the dropdown selection changes, I want to clear any text in the Autocomplete textbox. I have tried using a DOM selector in my listHandler() function called in the SearchDropdown component's `onSearchDropdownChange event. This method works in the browser console:

 function listHandler(searchKey) {
    document.getElementById("autocomplete").value = "";
    setKey(searchKey);
    const auto_key = { searchKey };
    let temp = "";
    if (auto_key.searchKey == 'name') {
        temp = { namesData };
        return setAutoData(temp.namesData);
    } else if (auto_key.searchKey == 'title') {
        temp = { titleData };
        return setAutoData(temp.titleData);
    } else if (auto_key.searchKey == 'email') {
        temp = { emailData };
        return setAutoData(temp.emailData);
    } else if (auto_key.searchKey == 'phone') {
        temp = { phoneData };
        return setAutoData(temp.phoneData);
    } else if (auto_key.searchKey == 'county') {
        temp = { countyData };
        return setAutoData(temp.countyData);
    } else if (auto_key.searchKey == 'affiliation') {
        temp = { affiliationData };
        return setAutoData(temp.affiliationData);
    } else {
        return setAutoData([]);
    }
}

Why doesn't this work in the code but does work in the browser? How can I clear this textbox when the dropdown selection changes?


Solution

  • To resolve this, I first had to add a handleReset function in my Autocomplete component:

    class Autocomplete extends Component {
    constructor(props) {
        super(props);
        this.state = {
            activeSuggestion: 0,
            filteredSuggestions: [],
            showSuggestions: false,
            userInput: ""
        };
    }
    
    handleReset = () => {
        this.setState({
            userInput: ""
        });
    };
    

    In my parent component, I had already added useRef() to reference my Autocomplete and SearchDropdown components.

    export const Table = () => {
    //For Sidebar Search
        const autoCompleteRef = useRef();
        const searchDropdownRef = useRef(); 
    

    I then called my original listHandler function when the SearchDropdown component selection changed and added my reference to the handleReset function using the AutocompleteRef like this:

     function listHandler(searchKey) {
        document.querySelector('input[id=autocomplete]').value = "";
        autoCompleteRef.current.handleReset();
        ...
     }
    

    It works now.