Exploring for the right search

James Wu
6 min readJan 10, 2021

As we progress in the modern era, more information is being shared every day. There is so much information in the world and so much data for users to intake. Besides the information bubble that the AI overloads wrap each person into, each person has the ability to search for information that validates their opinion. The search field on webpages has enabled users to find THE ONE article in the heaps of articles that justify their opinion.

To ensure that users can find what they are looking for, most applications have a search field allowing users to enter inputs to find, sort, and render information onto the screen. In scenarios where data is already loaded into the front end and render onto to the screen, the search field serves to filters the information and limits the data that is rendered on screen.

Each keystroke by the user enters into the search field changes the search variable which filters the data rendered onto the screen. Keystroke search is sufficient for instances where data was already loaded into the application, but it is not sufficient for instances where the search variable is used to query a backend database.

Fast typing users may outpace how fast servers can respond, keystrokes searches due to the outpacing may cause unnecessary loads to the server. The more inputs user enters, the more requests users are sending to the backend server. Fast typers are literally attacking the server with requests with lethal typing speeds! This leads to the second problem which impacts me personally. As a struggling junior developer, I have a limited amount of free queries to most free APIs in the market place. Each additional query means money out of my pockets and food off the table for my kids. Finally, if the users are searching by keystrokes, they might see a result that they do not want to see. If I am searching for the best movie of all time, Spaceballs (1987), I want to see the film Spaceballs show up on my search and not the scary movie, Office Space.

The alternative to keystroke search would be to execute the search after the user stops typing. Creating a time barrier between keystrokes and when the search variable activates the backend query will help us mitigate the problems that we mentioned above.

Before creating the timed search, let’s review what a search field is and how it works in ReactJS. A search consists of a simple HTML element called input.

<input>

The input element allows users to enter information into the application page.

With the code above, the image on the left is what users see on the screen. Users can enter any combination of keystrokes and the input element will reflect that change onto the screen. Usually, there is more information coded along with the input tag as per below, but those additional properties will not be discussed about.

<input type="text" id="name" name="name">

Moving on to ReactJS, the input JSX component is the HTML input element with more properties. JSX components allow developers to manipulate HTML elements and render them onto the screen in ReactJS. In addition to the properties of the HTML input element, the ReactJS input component has two additional properties that will aid us in creating a search field, value and onChange.

The value property determines what is actually inside the input component. If I set the value to “James”, then what we see is James inside the input box.

The displayed field will not change regardless of what users are entering. James will always be the displayed value of the input field. If the value property was not assigned or not utilized at all, then users would be able to change the input content to whatever they want, but without a value property assignment, this input field becomes an uncontrollable element. The problems associated with uncontrollable elements can be boiled down to interacting or accessing the uncontrollable element in ReactJS. Developers are going to need to write code to account for the mess that uncontrollable elements make. Think of the uncontrollable elements as brats!

Because we need the value property to control the input component, the input component is shackled by the value of the variable that we connected it to. The onChange property must be utilized to allow the input component to change dynamically as users type into the input field. The onChange property allows a callback function to be activated which can be used to adjust the content of the value property. I will be using the ReactJS hook useState for the search variable and the callback function.

const [ search, setSearch ] = useState("")

The code above invokes the useState hook and deconstructs it into two components. We have a string of “” assigned to the initial value of variable search and we have a setSearch function which updates the search variable. When a page with this hook loads for the first time, there should be an empty input field because the initial value of search is an empty street and the input field should be empty to reflect the value of the search variable.

<input
type='text'
name='search'
value={search}
onChange={ e => setSearch(e.target.value) }
/>

As users type into the input field, the onChange property is utilized to activate the setSearch function. The value inside the keystroke event (e) and is assigned to the value of search. Now the value of input should reflect the keystrokes entered by the user.

const displayData = () => {
const filteredData =data.filter(el=>
el.activity.toLowerCase().includes(search.toLowerCase()
))
return filteredData
}

The above is an example is how the search variable value is utilized to filter the data that is already loaded into our ReactJS application. As users enter keystrokes, the filter function filters the data and narrows it down to be more specified to the value of the search variable. As per the early passages, I cannot afford to have the search variable querying the database for every keystroke. Our application should only query the API database when the users have finished typing.

const [ movieQuery, setMovieQuery ] = useState("")useEffect(()=>{
const timeOutSearch = setTimeout(() =>
setMovieQuery(search),1000);
return () => clearTimeout(timeOutSearch)},
[search]
)

Above is code to help create a timed search instead of a keystroke search field. The useState is utilized to create the variable movieQuery and the function to change the value of movieQuery. By using an useEffect hook that activates only with changes to the search variable, the movieQuery variable will be assigned the value of the search variable after the process inside the function takes page. The movieQuery variable will be updated 1000 milliseconds (or 1 second) after the user has finished typing. The API call is now reconnected to movieQuery variable and has left the relationship it has with the search variable. The new relationship means that API calls will only occur when the user has stopped typing, which mitigates the problems we have with keystroke search.

My wallet feels so much better already! Users will see what they want to see and the application is no longer attacking the API server so many times. Different scenarios call for different search functions. To alleviate the burdens to my wallet, the timed search works better for applications that query a backend database.

Cheers!

James Wu

References:

https://www.w3schools.com/tags/tag_input.asp
https://reactjs.org/docs/forms.html
https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
https://reactjs.org/docs/hooks-intro.html

--

--

James Wu

Full Stack Developer | Software Engineer | React | React Native | Expo | Ruby on Rails | AWS S3