我正在尝试使用获取的用户列表过滤数组。用户以组件状态存储。我想通过输入中的文本过滤它。
问题:输入字母时,列表正在过滤,但是删除字母时,结果保持不变。
感谢帮助!
class App extends React.Component {
state = {
isLoading: true,
users: [],
error: null
}
fetchUsers() {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then(response => response.json())
.then(data =>
this.setState({
users: data,
isLoading: false,
})
)
.catch(error => this.setState({ error, isLoading: false }));
}
componentDidMount() {
this.fetchUsers();
}
onChangeHandler(e) {
console.log(e.target.value);
let newArray = this.state.users.filter((d)=>{
let searchValue = d.name.toLowerCase();
return searchValue.indexOf(e.target.value) !== -1;
});
console.log(newArray)
this.setState({
users:newArray
})
}
render() {
const {isLoading, users, error} = this.state;
return (
<div>
<h1>Users List</h1>
<input type="text" value={this.state.value} placeholder="Search by user name..." onChange={this.onChangeHandler.bind(this)}/>
{error ? <p>{error.message}</p> : null}
<ol>
{!isLoading ? (
users.map(user => {
const {username, name, id} = user;
return (
<li key={id}>
<p>{name} <span>@{username}</span></p>
</li>
);
})
) : (
<h3>Loading...</h3>
)}
</ol>
</div>
);
}
}
export default App;
答案 0 :(得分:0)
发生这种情况是因为您没有跟踪从API获得的原始值。一旦开始对其进行过滤,就会丢失完整列表。
我创建了一个codeandbox:https://codesandbox.io/s/nostalgic-sunset-jig33来解决您的问题。
我要做的是在initialUsers
中添加一个state
值,并使用它来存储来自API的值:
state = {
isLoading: true,
initialUsers: [],
users: [],
inputValue: "",
error: null
};
fetchUsers() {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then(response => response.json())
.then(data =>
this.setState({
initialUsers: data,
isLoading: false
})
)
.catch(error => this.setState({ error, isLoading: false }));
}
在render
方法中,我通过检查是否在input
元素中输入了文本来在显示原始列表的过滤列表之间切换
(!!inputValue ? users : initialUsers).map(
user => {
const { username, name, id } = user;
return (
<li key={id}>
<p>
{name} <span>@{username}</span>
</p>
</li>
);
}
)
答案 1 :(得分:0)
好吧,如果您从逻辑上看一下当前的解决方案,那么您将遇到以下情况
['John', 'Joe', 'Alfred']
J
,并将用户状态更新为['John', 'Joe']
J
的过滤器,并将用户状态更新为['John', 'Joe']
,导致组件完全忘记了Alfred
,在步骤3中删除了下摆。因此,您有几种选择,只需在映射之前过滤渲染,具体取决于有多少用户,这不应该那么糟,也可以在状态上创建多个属性,例如filteredUsers
,其中包含与您的过滤器匹配的users
列表,并改为使用该状态。
关于当前过滤器的一个很酷的事情是,随着结果集的减少,它总是可以更快地运行,所以这是一件好事,但是我怀疑您会与如此之多的用户打交道。
答案 2 :(得分:0)
要达到预期效果,请在使用setState更新用户后,使用以下选项将用户列表从API存储到变量中
apiUsers = [];
fetchUsers() {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then(response => response.json())
.then(data =>{
this.apiUsers = data;
this.setState({
users: data,
isLoading: false,
})
}
)
.catch(error => this.setState({ error, isLoading: false }));
}
在this.state.users
中使用新创建的变量-apiUsers
代替过滤onChangeHandler
onChangeHandler(e) {
console.log(e.target.value);
let newArray = this.apiUsers.filter((d)=>{
console.log(d)
let searchValue = d.name.toLowerCase();
return searchValue.indexOf(e.target.value) !== -1;
});
console.log(newArray)
this.setState({
users:newArray
})
}
工作代码以供参考-https://stackblitz.com/edit/react-sncf1e?file=index.js
问题::state.users
数组正在更新,而没有来自api的实际用户列表的副本