I am trying to use ref on a search input in my Header component which ISN'T a higher order component to my ResultsList component. I want to set focus on the Header's search input from the ResultsList component. It is intuitive from the Header because all I have to do is the below. What if I wanted to create a button in ResultsList which would focus on the input element in Header? How do I pass this ref? I have read about forwardRef but I am not passing my ref forwards. ResultsList is not a child of Header.
import React, { useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
const Header = () => {
const searchInput = useRef(null);
const history = useHistory();
const [searchValue, setSearchValue] = useState(keyword);
function handleChange(event) {
setSearchValue(event.target.value);
}
function handleSearch(event) {
event.preventDefault();
if(searchValue) {
history.push(`/search/${searchValue}`);
} else {
searchInput.current.focus();
}
}
return (
<form onSubmit={handleSearch} role="search">
<input
value={searchValue}
onChange={handleChange}
className="HeaderSearch__input"
id="header-search-input"
placeholder="Search a repository"
ref={searchInput}>
</input>
</form>
);
}
export default Header;
My App component looks like this
import React from 'react';
import Header from './Header';
import ResultsList from './ResultsList';
function App() {
return (
<>
<Header />
<ResultsList />
</>
);
}
export default App;
You will need to utilize the "Lifting State Up" pattern. Declare the react ref in
App
and pass it to both components, toHeader
to attach the ref to a node and toResultsList
to access the ref and set "focus".Attach and use the ref as you already are in
Header
Similarly, you can access
searchInputRef
inResultsList
component as well.Edit
If the children components are not direct descendants then you can utilize a react context to allow children to access the ref without needing to pass it as a prop though the React tree.
Create and export the context.
Provide the context to children in
App
Access the context in any sub child component
No matter how deeply nested
See this section if you happen to still be using class-based components.