Filter Data on Property Values in React

Andy Van Slaars
InstructorAndy Van Slaars

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

We want to be able to show only items in a certain status so in this lesson, we’ll add a flag to indicate which items to show, and create a function to filter the todos based on that value. We’ll take advantage of route based state to control the filtering behavior.

[00:00] I've created three tests for a function called filter to dos. We'll use these to create a function that takes in a route value and returns a filtered to do list based on the route.

[00:09] The first test is for the root route. The expectation here is that we will get all to dos back. The second test verifies that the \complete route returns only completed items. Finally, the third test verifies that we only return incomplete items for the slash active route.

[00:27] I'll run these using MPM test. We'll have three failing tests. We'll start by importing filter to dos into the test file. Now, we need to go into to do helpers and define filtered to dos. I'll start by exporting it. As a const, we'll call filter to dos. That's going to equal function that'll take in a list and our route as a string. We're going to switch on the route value.

[01:04] We'll start with the active case. We're going to compare this to what we expect to see in our route, which is going to be \active. In this case, we'll return list.filter, passing in our item and returning in if the item that is complete is false. Then for the complete case, we're going to do the opposite.

[01:30] I'm just going to duplicate these, and we'll say complete here. We'll remove the exclamation mark. This time if the item is complete, we'll return those. Then, we'll have a default which will just return the entire list.

[01:46] That should be all we need, I'll save this. We'll just verify that our test passed, and we're good to go.

[01:54] I've started the application in a browser and opened the app component source code. To integrate filtering into the app, we'll start by importing filtered to dos from to do helpers.

[02:06] In order to use the filter function, we need access to our route. That route is going to come from our context, because it belongs to the router component that's surrounding our entire app.

[02:16] I'm going to scroll down right under state, and I'm going to add a static value called context types. I'm going to set that to equal an object. I'm going to say that I want to be able to get the route and context. That is of type react.proptypes.string. That'll give me access to the route through context.

[02:39] I'm going to scroll down to the render method. Above the return, I'm going to add a new constant. I'm going to call it display to dos. I'm going to set that to equal a call to filter to dos.

[02:55] I'm going to pass in this.state.todos followed by this.context.route. Down to my to do list component where I'm passing this.state.todos into the to dos prop, I want to replace that with display to dos.

[03:13] I go ahead and save that. After reloading the browser, clicking active should filter down just to items that haven't been done. Clicking complete should leave just the single item that's already marked complete. All should bring back my entire list.

Matt
Matt
~ 5 years ago

As an alternative to a switch statement what do you feel about using an array to hold the filters something like this

const todoFilters = [
    { key: '/', fn: (item) => item },
    { key: '/active', fn: (item) => item.isComplete === false},
    { key: '/complete', fn: (item) => item.isComplete === true}
];

export const filter = (list, filter) => {
    let todoFilter = todoFilters.find((item) => item.key === filter);
    return list.filter(todoFilter.fn);
}
Andy Van Slaars
Andy Van Slaarsinstructor
~ 5 years ago

Matt,

I like that!

You might even take it one step further and create an generic identity function from the function you've defined for the / key. And you could shorten the other two if you like. Something like this:

const identity = x => x
const todoFilters = [
    { key: '/', fn: identity },
    { key: '/active', fn: (item) => !item.isComplete},
    { key: '/complete', fn: (item) => item.isComplete}
];

export const filter = (list, filter) => {
    let todoFilter = todoFilters.find((item) => item.key === filter);
    return list.filter(todoFilter.fn);
}
Matt
Matt
~ 5 years ago

Nice, even better.!!

Iain Maitland
Iain Maitland
~ 5 years ago

Where in my react chrome plugin can I examine the available context, would be nice to find where:

  static contextTypes = {
    route: React.PropTypes.string
  }

Is coming from...

Andy Van Slaars
Andy Van Slaarsinstructor
~ 5 years ago

Iain,

If you select a component that has access to context, like App or one of the Link components, you should see context in the right pane where you would expect to find state or props

Kartikey Tanna
Kartikey Tanna
~ 5 years ago

Had the problem but solved it. So removed the content