Search Results and Passing State Between React Components

May 28, 2020

Original Search Results Modal

I have a search form on my Blog, that sends a query to my API and responds with results in a modal. My first implementation was to display the results below the search box. 

 The presentation didn't work nicely, especially with some scroll bars I was using that were distorting the border radius. It also didn't always fit the screen height nicely, and sometimes looked like the text bled into the background text.
 
After a good pause in my Flickr Import script, I was looking at something different to work on. I thought about revisiting the search results, but didn't make the decision until I was on a random site. I saw a modal centered nicely on a site and thought that's how I should change my results to look.
 

Past Solution

If I was using JQuery or Vanilla JavaScript, I would have the search results use a selector against some class or the actual BODY tag, and apply the modal from there. I would also set the background color opacity. 
 

React Solution

Using strictly React on my Blog, I would have to solve this differently, using a state change instead.
 
So far I use state changes for the comment and search forms, and when switching between blog post's and my picture slideshow.
 
The state changes were done within the same component and are straight forward.
 
For the search results, I utilize a functional state with useState, and the comment forms use classes with setState.
 

Layout Component Composed of Header and Search

I have a main Layout component, that is composed of a Header and content component, which is pretty much the starting component for the site's design.
[Code]
 
 
The search form and results are in the Header component, (which I should separate in a future release).
 
Since my new full screen search overlay will need to start from the body, I have to set a state in the Layout component, in order to access the entire body of the website, set its opacity and center a search results modal on it.
 

Opaque Page Overlay

To solve this, I removed the class Layout from the existing div in 
components/blog/layouts/Layout.js
which was the container for the entire site. And I replaced it with a state.
<div className="Layout">
to
<div className={backgroundOverlay}>
I wasn't using the Layout class, so it wasn't a big deal to remove. If I still needed it, I could put an inline if statement appending it on.
 
Layout.js is a functional component, so I import useState and create state variable declarations:
let [backgroundOverlay, setBackgroundOverlay] = useState("");
Layout state changes are in this commit.
[Code

Passing Layout Overlay State to Header Component

The important part I was unsure about, was how to pass the state from the Layout component to the Header component.
 
This was easily done by simply passing a handle to setBackgroundOverlay as an argument to the Header (I just reused the same name):
<Header setBackgroundOverlay={setBackgroundOverlay} />
From there I was able to access the {backgroundOverlay} state in the header. 
 
Any time I called setBackgroundOverlay in the header, the state would propagate back up to the Layout. 
setBackgroundOverlay replaces className={backgroundOverlay} with an overlay-background class name I defined in my stylesheet.
overlay-background took care of setting the screens opacity, which put my search results nicely in the browser's foreground. 

Refactoring Search Results

I centered the search results, took out the scrollbar and just let the user scroll the page down to see the results.
 
I am fairly happy with the appearance.
 
In addition, I also realized when the browsers build-in autocomplete was triggered to auto-suggest keywords based on past searches, I made sure it triggered a search on the words suggested.
 
While triggering the search suggestions, I accidentally enabled my search to send each iteration of the search characters to my API search, performing the search in real time. 
 
On a high traffic site, performance would be a concern, but I don't think I'll have that issue on my site. It also looked pretty good and I kept my accidental bug as a feature.

Comments

New Comment