如何在React&中进行排序基于排序过滤?

时间:2017-07-17 16:40:53

标签: javascript json reactjs sorting filter

如何在React中显示排序依据? 并且还会根据下拉列表male, female or all中选择的排序 过滤

// Gather list of names
const names = data
// filtering out the names that...
.filter((person, i) => {
  return (
    // ...are already favourited
    favourites.indexOf(person.id) === -1
    // ...are not matching the current search value
    && !person.name.toLowerCase().indexOf(input)
  )
})
// ...output a <Name /> component for each name
.map((person, i) => {
// only display names that match current input string
  return (
    <Name 
      id={person.id}
      key={i}
      info={person}
      handleFavourite={(id) => addFavourite(id)}
    />
  )
})

const {
  Component
} = React;

/* ############################ */
/* ##### Single baby name ##### */
/* ############################ */

const Name = ({
    id,
    info,
    handleFavourite
  }) =>
  <
  li className = {
    info.sex
  }
onClick = {
    () => handleFavourite(id)
  } > {
    info.name
  } <
  /li>;

/* ##################### */
/* ##### Shortlist ##### */
/* ##################### */

const ShortList = ({
  favourites,
  data,
  deleteFavourite
}) => {
  const hasFavourites = favourites.length > 0;
  const favList = favourites.map((fav, i) => {
    return ( <
      Name id = {
        i
      }
      key = {
        i
      }
      info = {
        data[fav]
      }
      handleFavourite = {
        id => deleteFavourite(id)
      }
      />
    );
  });
  return ( <
      div className = "favourites" >
      <
      h4 > {
        hasFavourites ? "Your Shortlist" : "Click on a name to shortlist it.."
      } <
      /h4> <
      ul > {
        favList
      } <
      /ul> {
      hasFavourites && < hr / >
    } <
    /div>
);
};

/* ########################### */
/* ##### Baby names list ##### */
/* ########################### */

const NamesList = ({
  data,
  filter,
  favourites,
  addFavourite
}) => {
  const input = filter.toLowerCase();

  // Gather list of names
  const names = data
    // filtering out the names that...
    .filter((person, i) => {
      return (
        // ...are already favourited
        favourites.indexOf(person.id) === -1 &&
        // ...are not matching the current search value
        !person.name.toLowerCase().indexOf(input)
      );
    })
    // ...output a <Name /> component for each name
    .map((person, i) => {
      // only display names that match current input string
      return ( <
        Name id = {
          person.id
        }
        key = {
          i
        }
        info = {
          person
        }
        handleFavourite = {
          id => addFavourite(id)
        }
        />
      );
    });

  /* ##### the component's output ##### */
  return ( <
    ul > {
      names
    } <
    /ul>
  );
};

/* ###################### */
/* ##### Search bar ##### */
/* ###################### */

// need a component class here
// since we are using `refs`
class Search extends Component {
  render() {
    const {
      filterVal,
      filterUpdate
    } = this.props;
    return ( <
      form >
      <
      input type = "text"
      ref = "filterInput"
      placeholder = "Search.."
      // binding the input value to state
      value = {
        filterVal
      }
      onChange = {
        () => {
          filterUpdate(this.refs.filterInput.value);
        }
      }
      />

      <
      div className = "repo-filter-menu" >
      <
      strong > Sort by: < /strong> <
      div className = "filter-menu" >
      <
      span > All < /span> <
      ul className = "dropdown-menu" >
      <
      li className = "repo-filter-name hide" > All < /li> <
      li className = "repo-filter-name hide" > Male < /li> <
      li className = "repo-filter-name hide" > Female < /li> < /
      ul > <
      /div> < /
      div >

      <
      /form>
    );
  }
}

/* ############################## */
/* ##### Main app component ##### */
/* ############################## */

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      filterText: "",
      favourites: []
    };
  }

  // update filterText in state when user types
  filterUpdate(value) {
    this.setState({
      filterText: value
    });
  }

  // add clicked name ID to the favourites array
  addFavourite(id) {
    const newSet = this.state.favourites.concat([id]);
    this.setState({
      favourites: newSet
    });
  }

  // remove ID from the favourites array
  deleteFavourite(id) {
    const {
      favourites
    } = this.state;
    const newList = [...favourites.slice(0, id), ...favourites.slice(id + 1)];
    this.setState({
      favourites: newList
    });
  }

  render() {
    const hasSearch = this.state.filterText.length > 0;
    return ( <
      div >
      <
      header >
      <
      Search filterVal = {
        this.state.filterText
      }
      filterUpdate = {
        this.filterUpdate.bind(this)
      }
      /> < /
      header > <
      main >

      <
      ShortList data = {
        this.props.data
      }
      favourites = {
        this.state.favourites
      }
      deleteFavourite = {
        this.deleteFavourite.bind(this)
      }
      />

      <
      NamesList data = {
        this.props.data
      }
      filter = {
        this.state.filterText
      }
      favourites = {
        this.state.favourites
      }
      addFavourite = {
        this.addFavourite.bind(this)
      }
      /> {
      /* 
                  Show only if user has typed in search.
                  To reset the input field, we pass an 
                  empty value to the filterUpdate method
                */
    } {
      hasSearch &&
        <
        button onClick = {
          this.filterUpdate.bind(this, "")
        } >
        Clear Search <
        /button>}

        <
        div className = "credit" >
        Source of names list: {
          " "
        } < a
      href = "https://www.yahoo.com/parenting/atticus-tops-baby-names-2015-124073377716.html"
      target = "_blank" >
        Yahoo - Top Baby Names in 2015 <
        /a> < /
        div > <
        /main> < /
        div >
    );
  }
}

/* ########################## */
/* ##### The names data ##### */
/* ########################## */

const PEOPLE = [{
    id: 0,
    name: "Aria",
    sex: "girl"
  },
  {
    id: 1,
    name: "Logan",
    sex: "boy"
  },
  {
    id: 2,
    name: "Quinn",
    sex: "girl"
  },
  {
    id: 3,
    name: "Kai",
    sex: "boy"
  },
  {
    id: 4,
    name: "Dashiell",
    sex: "boy"
  },
  {
    id: 5,
    name: "John",
    sex: "boy"
  },
  {
    id: 6,
    name: "Seraphina",
    sex: "girl"
  },
  {
    id: 7,
    name: "Caroline",
    sex: "girl"
  },
  {
    id: 8,
    name: "Tobias",
    sex: "boy"
  },
  {
    id: 9,
    name: "Harper",
    sex: "girl"
  },
  {
    id: 10,
    name: "Mabe",
    sex: "girl"
  },
  {
    id: 11,
    name: "Iris",
    sex: "girl"
  },
  {
    id: 12,
    name: "Beatrice",
    sex: "girl"
  },
  {
    id: 13,
    name: "Knox",
    sex: "boy"
  },
  {
    id: 14,
    name: "August",
    sex: "boy"
  },
  {
    id: 15,
    name: "Poppy",
    sex: "girl"
  },
  {
    id: 16,
    name: "Aurora",
    sex: "girl"
  },
  {
    id: 17,
    name: "Wyatt",
    sex: "boy"
  },
  {
    id: 18,
    name: "Ezra",
    sex: "boy"
  },
  {
    id: 19,
    name: "Emily",
    sex: "girl"
  },
  {
    id: 20,
    name: "Sebastian",
    sex: "boy"
  },
  {
    id: 21,
    name: "Gabriel",
    sex: "boy"
  },
  {
    id: 22,
    name: "Charlie",
    sex: "boy"
  },
  {
    id: 23,
    name: "Isabella",
    sex: "girl"
  },
  {
    id: 24,
    name: "Elliot",
    sex: "boy"
  },
  {
    id: 25,
    name: "Declan",
    sex: "boy"
  },
  {
    id: 26,
    name: "Benjamin",
    sex: "boy"
  },
  {
    id: 27,
    name: "Gemma",
    sex: "girl"
  },
  {
    id: 28,
    name: "Lucas",
    sex: "boy"
  },
  {
    id: 29,
    name: "Chloe",
    sex: "girl"
  },
  {
    id: 30,
    name: "Khaleesi",
    sex: "girl"
  },
  {
    id: 31,
    name: "Austin",
    sex: "boy"
  },
  {
    id: 32,
    name: "Matilda",
    sex: "girl"
  },
  {
    id: 33,
    name: "Grayson",
    sex: "boy"
  },
  {
    id: 34,
    name: "Beckett",
    sex: "boy"
  },
  {
    id: 35,
    name: "Nicholas",
    sex: "boy"
  },
  {
    id: 36,
    name: "Ronan",
    sex: "boy"
  },
  {
    id: 37,
    name: "Eliza",
    sex: "girl"
  },
  {
    id: 38,
    name: "Imogen",
    sex: "girl"
  },
  {
    id: 39,
    name: "Amelia",
    sex: "girl"
  },
  {
    id: 40,
    name: "Nathaniel",
    sex: "boy"
  },
  {
    id: 41,
    name: "Ryker",
    sex: "boy"
  },
  {
    id: 42,
    name: "Olivia",
    sex: "girl"
  },
  {
    id: 43,
    name: "Leo",
    sex: "boy"
  },
  {
    id: 44,
    name: "Zane",
    sex: "boy"
  },
  {
    id: 45,
    name: "Grace",
    sex: "girl"
  },
  {
    id: 46,
    name: "Owen",
    sex: "boy"
  },
  {
    id: 47,
    name: "Clara",
    sex: "girl"
  },
  {
    id: 48,
    name: "Julian",
    sex: "boy"
  },
  {
    id: 49,
    name: "Caleb",
    sex: "boy"
  },
  {
    id: 50,
    name: "Nolan",
    sex: "boy"
  },
  {
    id: 51,
    name: "Roman",
    sex: "boy"
  },
  {
    id: 52,
    name: "Felix",
    sex: "boy"
  },
  {
    id: 53,
    name: "Aryan",
    sex: "boy"
  },
  {
    id: 54,
    name: "Lily",
    sex: "girl"
  },
  {
    id: 55,
    name: "Sloane",
    sex: "girl"
  },
  {
    id: 56,
    name: "Zoe",
    sex: "girl"
  },
  {
    id: 57,
    name: "Penelope",
    sex: "girl"
  },
  {
    id: 58,
    name: "Evangeline",
    sex: "girl"
  },
  {
    id: 59,
    name: "Julia",
    sex: "girl"
  },
  {
    id: 60,
    name: "Theo",
    sex: "boy"
  },
  {
    id: 61,
    name: "Nathan",
    sex: "boy"
  },
  {
    id: 62,
    name: "Juliet",
    sex: "girl"
  },
  {
    id: 63,
    name: "Josiah",
    sex: "boy"
  },
  {
    id: 64,
    name: "Harrison",
    sex: "boy"
  },
  {
    id: 65,
    name: "Archer",
    sex: "boy"
  },
  {
    id: 66,
    name: "Ellie",
    sex: "girl"
  },
  {
    id: 67,
    name: "Rowan",
    sex: "boy"
  },
  {
    id: 68,
    name: "Eden",
    sex: "girl"
  },
  {
    id: 69,
    name: "Rhys",
    sex: "boy"
  },
  {
    id: 70,
    name: "Evelyn",
    sex: "girl"
  },
  {
    id: 71,
    name: "Isabel",
    sex: "girl"
  },
  {
    id: 72,
    name: "Mae",
    sex: "girl"
  },
  {
    id: 73,
    name: "Mila",
    sex: "girl"
  },
  {
    id: 74,
    name: "Emmett",
    sex: "boy"
  },
  {
    id: 75,
    name: "Rose",
    sex: "girl"
  },
  {
    id: 76,
    name: "Axel",
    sex: "boy"
  },
  {
    id: 77,
    name: "Willow",
    sex: "girl"
  },
  {
    id: 78,
    name: "Cora",
    sex: "girl"
  },
  {
    id: 79,
    name: "David",
    sex: "boy"
  },
  {
    id: 80,
    name: "Miles",
    sex: "boy"
  },
  {
    id: 81,
    name: "Clementine",
    sex: "girl"
  },
  {
    id: 82,
    name: "Sophia",
    sex: "girl"
  },
  {
    id: 83,
    name: "Eloise",
    sex: "girl"
  },
  {
    id: 84,
    name: "Everly",
    sex: "girl"
  },
  {
    id: 85,
    name: "Maeve",
    sex: "girl"
  },
  {
    id: 86,
    name: "Nora",
    sex: "girl"
  },
  {
    id: 87,
    name: "Lucy",
    sex: "girl"
  },
  {
    id: 88,
    name: "Adeline",
    sex: "girl"
  },
  {
    id: 89,
    name: "Hazel",
    sex: "girl"
  },
  {
    id: 90,
    name: "Oscar",
    sex: "boy"
  },
  {
    id: 91,
    name: "Ruby",
    sex: "girl"
  },
  {
    id: 92,
    name: "Silas",
    sex: "boy"
  },
  {
    id: 93,
    name: "Mia",
    sex: "girl"
  },
  {
    id: 94,
    name: "Jude",
    sex: "boy"
  },
  {
    id: 95,
    name: "Evie",
    sex: "girl"
  },
  {
    id: 96,
    name: "Luna",
    sex: "girl"
  },
  {
    id: 97,
    name: "Wren",
    sex: "girl"
  },
  {
    id: 98,
    name: "Hadley",
    sex: "girl"
  },
  {
    id: 99,
    name: "Ivy",
    sex: "girl"
  },
  {
    id: 100,
    name: "Lachlan",
    sex: "boy"
  },
  {
    id: 101,
    name: "Emmeline",
    sex: "girl"
  },
  {
    id: 102,
    name: "Hugo",
    sex: "boy"
  },
  {
    id: 103,
    name: "Stella",
    sex: "girl"
  },
  {
    id: 104,
    name: "Maddox",
    sex: "boy"
  },
  {
    id: 105,
    name: "Asher",
    sex: "boy"
  },
  {
    id: 106,
    name: "Jayden",
    sex: "boy"
  },
  {
    id: 107,
    name: "Daisy",
    sex: "girl"
  },
  {
    id: 108,
    name: "Callum",
    sex: "boy"
  },
  {
    id: 109,
    name: "Jasper",
    sex: "boy"
  },
  {
    id: 110,
    name: "Emma",
    sex: "girl"
  },
  {
    id: 111,
    name: "Claire",
    sex: "girl"
  },
  {
    id: 112,
    name: "Lola",
    sex: "girl"
  },
  {
    id: 113,
    name: "Jonah",
    sex: "boy"
  },
  {
    id: 114,
    name: "Sienna",
    sex: "girl"
  },
  {
    id: 115,
    name: "Ada",
    sex: "girl"
  },
  {
    id: 116,
    name: "Scarlett",
    sex: "girl"
  },
  {
    id: 117,
    name: "Sawyer",
    sex: "boy"
  },
  {
    id: 118,
    name: "Hannah",
    sex: "girl"
  },
  {
    id: 119,
    name: "Soren",
    sex: "boy"
  },
  {
    id: 120,
    name: "Maya",
    sex: "girl"
  },
  {
    id: 121,
    name: "Arabella",
    sex: "girl"
  },
  {
    id: 122,
    name: "Beau",
    sex: "boy"
  },
  {
    id: 123,
    name: "Maxwell",
    sex: "boy"
  },
  {
    id: 124,
    name: "Anna",
    sex: "girl"
  },
  {
    id: 125,
    name: "Lila",
    sex: "girl"
  },
  {
    id: 126,
    name: "Sadie",
    sex: "girl"
  },
  {
    id: 127,
    name: "James",
    sex: "boy"
  },
  {
    id: 128,
    name: "Arthur",
    sex: "boy"
  },
  {
    id: 129,
    name: "Aurelia",
    sex: "girl"
  },
  {
    id: 130,
    name: "Samuel",
    sex: "boy"
  },
  {
    id: 131,
    name: "Atticus",
    sex: "boy"
  },
  {
    id: 132,
    name: "Bodhi",
    sex: "boy"
  },
  {
    id: 133,
    name: "Elijah",
    sex: "boy"
  },
  {
    id: 134,
    name: "Griffin",
    sex: "boy"
  },
  {
    id: 135,
    name: "Graham",
    sex: "boy"
  },
  {
    id: 136,
    name: "Weston",
    sex: "boy"
  },
  {
    id: 137,
    name: "Hudson",
    sex: "boy"
  },
  {
    id: 138,
    name: "Henry",
    sex: "boy"
  },
  {
    id: 139,
    name: "Levi",
    sex: "boy"
  },
  {
    id: 140,
    name: "Nova",
    sex: "girl"
  },
  {
    id: 141,
    name: "Margaret",
    sex: "girl"
  },
  {
    id: 142,
    name: "Adelaide",
    sex: "girl"
  },
  {
    id: 143,
    name: "Audrey",
    sex: "girl"
  },
  {
    id: 144,
    name: "Jane",
    sex: "girl"
  },
  {
    id: 145,
    name: "Alice",
    sex: "girl"
  },
  {
    id: 146,
    name: "Simon",
    sex: "boy"
  },
  {
    id: 147,
    name: "Ella",
    sex: "girl"
  },
  {
    id: 148,
    name: "Violet",
    sex: "girl"
  },
  {
    id: 149,
    name: "Thomas",
    sex: "boy"
  },
  {
    id: 150,
    name: "Madeline",
    sex: "girl"
  },
  {
    id: 151,
    name: "Genevieve",
    sex: "girl"
  },
  {
    id: 152,
    name: "Oliver",
    sex: "boy"
  },
  {
    id: 153,
    name: "Lydia",
    sex: "girl"
  },
  {
    id: 154,
    name: "Ethan",
    sex: "boy"
  },
  {
    id: 155,
    name: "Liam",
    sex: "boy"
  },
  {
    id: 156,
    name: "Alexander",
    sex: "boy"
  },
  {
    id: 157,
    name: "Wesley",
    sex: "boy"
  },
  {
    id: 158,
    name: "William",
    sex: "boy"
  },
  {
    id: 159,
    name: "Harlow",
    sex: "girl"
  },
  {
    id: 160,
    name: "Isaac",
    sex: "boy"
  },
  {
    id: 161,
    name: "Eliana",
    sex: "girl"
  },
  {
    id: 162,
    name: "Esme",
    sex: "girl"
  },
  {
    id: 163,
    name: "Elizabeth",
    sex: "girl"
  },
  {
    id: 164,
    name: "Xavier",
    sex: "boy"
  },
  {
    id: 165,
    name: "Piper",
    sex: "girl"
  },
  {
    id: 166,
    name: "Andrew",
    sex: "boy"
  },
  {
    id: 167,
    name: "Abigail",
    sex: "girl"
  },
  {
    id: 168,
    name: "Olive",
    sex: "girl"
  },
  {
    id: 169,
    name: "Everett",
    sex: "boy"
  },
  {
    id: 170,
    name: "Lincoln",
    sex: "boy"
  },
  {
    id: 171,
    name: "Eli",
    sex: "boy"
  },
  {
    id: 172,
    name: "Elodie",
    sex: "girl"
  },
  {
    id: 173,
    name: "Josephine",
    sex: "girl"
  },
  {
    id: 174,
    name: "Thea",
    sex: "girl"
  },
  {
    id: 175,
    name: "Emilia",
    sex: "girl"
  },
  {
    id: 176,
    name: "Florence",
    sex: "girl"
  },
  {
    id: 177,
    name: "Ava",
    sex: "girl"
  },
  {
    id: 178,
    name: "Isla",
    sex: "girl"
  },
  {
    id: 179,
    name: "Willa",
    sex: "girl"
  },
  {
    id: 180,
    name: "Milo",
    sex: "boy"
  },
  {
    id: 181,
    name: "Charlotte",
    sex: "girl"
  },
  {
    id: 182,
    name: "Noah",
    sex: "boy"
  },
  {
    id: 183,
    name: "Matthew",
    sex: "boy"
  },
  {
    id: 184,
    name: "Luca",
    sex: "boy"
  },
  {
    id: 185,
    name: "Finn",
    sex: "boy"
  },
  {
    id: 186,
    name: "Cordelia",
    sex: "girl"
  },
  {
    id: 187,
    name: "Theodore",
    sex: "boy"
  },
  {
    id: 188,
    name: "George",
    sex: "boy"
  },
  {
    id: 189,
    name: "Jackson",
    sex: "boy"
  },
  {
    id: 190,
    name: "Jacob",
    sex: "boy"
  },
  {
    id: 191,
    name: "Eleanor",
    sex: "girl"
  },
  {
    id: 192,
    name: "Daniel",
    sex: "boy"
  },
  {
    id: 193,
    name: "Ryder",
    sex: "boy"
  },
  {
    id: 194,
    name: "Annabelle",
    sex: "girl"
  },
  {
    id: 195,
    name: "Zachary",
    sex: "boy"
  },
  {
    id: 196,
    name: "Luke",
    sex: "boy"
  },
  {
    id: 197,
    name: "Jack",
    sex: "boy"
  },
  {
    id: 198,
    name: "Charles",
    sex: "boy"
  },
  {
    id: 199,
    name: "Bennett",
    sex: "boy"
  }
];

ReactDOM.render( < App data = {
      PEOPLE
    }
    />, document.getElementById("root"));
* {
  box-sizing: border-box;
}

header {
  background: #3498db;
  margin-bottom: 2rem;
}

main {
  padding: 0 2rem;
}

input[type='text'] {
  margin: 1rem;
  background: #fff;
  font-size: 1.3rem;
  border: none;
  box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
  border-radius: 3px;
  padding: 0 2rem;
  width: calc(100% - 2rem);
  height: 4rem;
}

ul {
  padding: 0;
}

li {
  position: relative;
  list-style: none;
  display: inline-block;
  padding: 0.25rem 0.75rem;
  margin: 2px;
  border-radius: 3px;
}

li:hover {
  cursor: pointer;
}

li.girl {
  background: #ffc6e5;
  color: #940050;
}

li.girl:hover {
  background: #ffadd9;
}

li.boy {
  background: #a0cfee;
  color: #16527a;
}

li.boy:hover {
  background: #8bc4ea;
}

.favourites li:hover:before {
  content: '\00D7';
  position: absolute;
  top: -0.5rem;
  right: -0.3rem;
  width: 1rem;
  height: 1rem;
  z-index: 2;
  text-align: center;
  line-height: 1;
  font-size: 0.9rem;
  vertical-align: middle;
  border-radius: 50%;
  background: #ff6347;
  border: solid 2px #fff;
  color: #fff;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
}

.favourites h4 {
  padding: 1rem 0;
  font-weight: 400;
  font-size: 1.3rem;
  margin: 0;
  color: #b3b3b3;
}

.favourites hr {
  border-bottom: 0;
  border-top: solid 1px #e6e6e6;
  margin: 1.75rem 0;
}

.credit {
  padding: 1rem 0;
  color: #b3b3b3;
}

.credit a {
  color: #3498db;
}

button {
  background: #d7d7d7;
  color: #3b3b3b;
  padding: 0.6rem 1rem;
  font-size: 0.8rem;
  border: solid 1px #c7c7c7;
  margin: 1rem 0;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
  border-radius: 3px;
  outline: none;
}

button:hover {
  background: #ddd;
}

.repo-filter-menu {
  text-align: right;
  padding: 0 2rem 1em;
}

.filter-menu {
  position: relative;
  display: inline-block;
  color: white;
}

.filter-menu .dropdown-menu {
  color: #333;
  display: none;
  position: absolute;
  right: 0;
  background-color: white;
  min-width: 100px;
  box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.filter-menu:hover .dropdown-menu {
  display: block;
}

.filter-menu ul {
  margin-top: 0;
  padding: 0;
  list-style: none;
}

.filter-menu ul li {
  display: block;
}

.filter-menu ul li:hove {
  background-color: #efefef;
}
<link rel="stylesheet" , href="https://necolas.github.io/normalize.css/7.0.0/normalize.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

演示:https://codepen.io/anon/pen/webvam

1 个答案:

答案 0 :(得分:0)

我已经分叉了您的代码并对其进行了一些更改,添加了一个简单的排序name并按malefemaleall进行过滤。我已从li标记中删除了repo-filter-name hide个类,因为它们在codepen中查看时会导致一些问题。这有什么接近你期望的吗?

https://codepen.io/saurabhgour/full/NgVGPz