Implementing Search/Filter a list on Redux — React

Yao Xiao
4 min readOct 25, 2016

--

This post walks through my attempt at creating a search mechanism in React on data stored in Redux, which has led me to rethink the ways that these underlying frameworks were “mean” to be used (especially Redux).

Backstory:

I’ve been recently learning and dabbling through React with Redux, trying to “get with the times” of front-end engineering, which somehow has you rethinking about the entire Front-end landscape every couple of years, but that in itself deserves another (or 2.. or 10) post.

So I’ve been working on an web app that essentially tries to visualize data about a particular organization/team/person on Github, and I’ve come to a problem where I need to implement a search bar that allows users to filter down on people.

If you don’t have a background in Redux, it basically is a framework that allows you to store your app state inside an object tree, in which the only way to change that state is go to through actions to “describe” what’s going to happen, then which reducers to tell you how that action transforms the state tree.

Requirement:

UI: Simple Search Bar.
Functionality: As the user types, filter down the list of items to match the search query.

Simple enough right?

The Problem:

Since the list of the items that I have is shared across many components within my application, I’ve decided that it is a great candidate to be stored inside the Redux state tree. Below is how I did it.

The left screenshot describes the action that I took, which sends an API request (and returns a object with actiontype and a promise). The right screenshot is the Reducer that checks the actionType then transforms the state with the new Data.

When the items are in the Redux State, ideally my React component would just read directly from Redux State, but then how do I tell my component what part of that state to show?

A couple of my friends/colleagues are convinced that once you start using Redux…. Everything should be in Redux, I respectfully disagree, and will write another article about it. As you can see later on how in this example that would not work.

The Solution:

So Redux State is the single source of truth and we shouldn’t transform the state unless we need to, which means a simple way of thinking about this is having a “currentlyDisplayed” state that shows the currently filtered, and that state would live inside the component itself since no other component would use it. Every time the input box changes, we would call filter on the redux state, THEN calling react’s setState to put the result into the component state.

Below is how I implemented that.
Couple things to note:
- this.props.people is the Redux Application Level state (mapped using mapStateToProps
- this.state is the component level state only visible by the component

Initialize the COMPONENT (not redux) state to take the value from redux state (this.props.people because redux maps state to props)
this function is triggered whenever the input is changed

See above that we first call the filter function on the state stored in Redux (because that’s the source of truth), then we set the component level state for both the searchTerm and the currentlyDisplayed, this way we’re keeping the scope of this problem within the component. The JSX code which renders the displayed would be binded to currentlyDisplayed now rather than the Redux state.

we’re rendering using the currentlyDisplayed (component state)

So that’s it! It’s really that simple, but it’s more of wrapping your head around the different ways to use react with redux when it comes to state like this. In this particular case, the data I had was shared across components which is why I chose to put it inside the application level store, a specific component that uses it might need to do data filtering on it, which in a way creates a different data that should live in the component level because it’s specific to that component. At first it might seem like I’m duplicating state, but “currentlyDisplayed” and “allPeople” are really two different things. (even if one is a subset of another)

This is an example of the working search function

Yay for searching!

--

--

Yao Xiao

Frontend Engineer @ Medallia, BCFM University of Waterloo