我在应用程序中使用过滤器,该过滤器限制了用户列表的输出。在我的codesandbox
中查看具有相同概念的示例这个想法是该列表接受多个过滤器值以根据需要缩小搜索范围。输入任何字符时,第一个过滤器工作正常,但是在第二个过滤器输入中进行切换然后再键入一些内容,则会重新呈现列表并覆盖第一个过滤器的搜索结果。
主要组件:
<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 });
};
我确实计划使用更多的过滤器,并且该列表不应重新呈现。 有什么方法可以防止这种情况或制定出更好的解决方案? 大型网站如何应用其过滤器?
答案 0 :(得分:0)
您可以将电子邮件的过滤器值和名称都设置为状态,然后触发一个过滤器功能,将这两个值用于最终结果。您还应该以组件或父组件的状态存储filter的值。这样一来,您就不会覆盖您的搜索值。
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>
);
}
}
答案 1 :(得分:0)
这里是my solution的示例。通常,“大型网站”在不必要时会尽可能减少过滤时间。同样,我将添加一个setTimeout()以便不立即对每个输入进行过滤,并且如果用户在400毫秒内键入(例如),则清除所述超时。
在您的过滤器组件中,我会跟踪过滤后的单词:
class Filters extends React.Component {
constructor(props) {
super(props);
this.state = {
email: "",
name: ""
};
}
handleChange = event => {
const { onChange } = this.props;
let key = "email";
if (event.target.name === "name") {
key = "name";
}
this.setState({ [key]: event.target.value });
onChange({ email: this.state.email, name: this.state.name });
};
render() {
const { onChange } = this.props;
return (
<div className="filters">
<input
name="name"
type="text"
placeholder="Search by name"
onInput={this.handleChange}
/>
<input
name="email"
type="text"
placeholder="Search by email"
onInput={this.handleChange}
/>
</div>
);
}
}
然后在您的App组件中,我将创建两个不同的过滤器,这样,如果填写了“ name”属性,它将优先考虑:
handleFilter = data => {
let updateUsers = this.state.users;
console.log(data);
if (data.name.length > 0) {
updateUsers = updateUsers.filter(user => {
return user.name.toLowerCase().includes(data.name);
});
}
if (data.email.length > 0) {
updateUsers = updateUsers.filter(user => {
return user.email.toLowerCase().includes(data.email);
});
}
this.setState({ filteredUsers: updateUsers });
};