首页 > 解决方案 > 使用多个过滤器重新渲染组件

问题描述

我在应用程序中使用过滤器来限制用户列表的输出。请参阅我的代码框中相同概念的示例

这个想法是该列表接受多个过滤器值以根据需要缩小搜索范围。第一个过滤器在输入任何字符时都可以正常工作,但是切换然后在第二个过滤器输入中输入一些内容会重新呈现列表并覆盖第一个过滤器的搜索结果。

主要成分:

  <div className="App">
    <Filters onChange={this.handleFilter} />
    <div className="list">
      <List users={filteredUsers} />
    </div>
  </div>

过滤输入:

<div className="filters">
  <input
    name="name"
    type="text"
    placeholder="Search by name"
    onChange={props.onChange}
  />
  <input
    name="email"
    type="text"
    placeholder="Search by email"
    onChange={props.onChange}
  />
</div>

过滤器处理程序:

  handleFilter = event => {
    const target = event.target;
    let updateUsers = this.state.users;
    updateUsers = updateUsers.filter(user => {
      let type;
      if (target.name === "name") {
        type = user.name;
      } else if (target.name === "email") {
        type = user.email;
      }
      return type.toLowerCase().search(target.value.toLowerCase()) !== -1;
    });
    this.setState({ filteredUsers: updateUsers });
  };

我确实计划使用更多过滤器,并且该列表不应重新呈现。有什么方法可以防止这种情况或找到更好的解决方案?大网站如何应用他们的过滤器?

标签: javascriptreactjs

解决方案


您可以将 email 和 name 的过滤器值都设置为 state,然后触发一个过滤器函数,将这两个值用于最终结果。您还应该将过滤器的值存储在状态中,无论是组件还是父级。这样,您的搜索值就不会被覆盖。

import React, { Component } from "react";

const Filters = ({ onChange, emailFilterValue, nameFilterValue }) => (
  <div className="filters">
    <input
      name="name"
      type="text"
      placeholder="Search by name"
      onChange={onChange}
      value={nameFilterValue}
    />
    <input
      name="email"
      type="text"
      placeholder="Search by email"
      onChange={onChange}
      value={emailFilterValue}
    />
  </div>
);

class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [],
      nameFilter: "",
      emailFilter: ""
    };
  }

  handleFilter = e => {
    const { name, value } = e.target;
    if (name === "email") {
      this.setState({ emailFilter: value });
    } else if (name === "name") {
      this.setState({ nameFilter: value });
    }
    this.filterUsers();
  };

  filterUsers = () => {
    const { users, nameFilter, emailFilter } = this.state;
    let updateUsers = users.slice();
    if (nameFilter.length > "") {
      // do your search based on name
    }
    if (emailFilter.length > "") {
      // then apply email filter
    }
    this.setState({ users: updateUsers });
  };

  render() {
    return (
      <div className="App">
        <Filters
          onChange={this.handleFilter}
          emailFilterValue={this.state.emailFilter}
          nameFilterValue={this.state.nameFilter}
        />
        <div className="list">
          <List users={filteredUsers} />
        </div>
      </div>
    );
  }
}

推荐阅读