reactjs - 过滤列表时如何保留选中的值
问题描述
我有一个过滤函数 'filterUsers' 处理 'filteredUsers' 对象数组。每个对象都呈现为带有一些数据和复选框的列表项。每次用户更改文本输入值时都会触发该函数。如果在过滤掉某个项目时检查了该项目,则检查的值将丢失。我需要一个解决方案来保留选中的值。
const UsersList = () => {
const { users } = useContext(UsersContext);
const [checkedUsersIds, setCheckedUsersIds] = useState([]);
const [filteredUsers, setFilteredUsers] = useState([]);
useEffect(() => setFilteredUsers(users), [users]);
useEffect(() => console.log(checkedUsersIds), [checkedUsersIds]);
const checkUsers = async e => {
if (e.target.checked) {
const checkedUser = users.find(user => user.id === Number(e.target.name));
setCheckedUsersIds([...checkedUsersIds, checkedUser.id]);
} else {
setCheckedUsersIds(checkedUsersIds.filter(user => user !== Number(e.target.name)));
}
};
const filterUsers = e => {
setFilteredUsers(
users.filter(
user =>
user.first_name.toLowerCase().includes(e.target.value.toLowerCase().trim()) ||
user.last_name.toLowerCase().includes(e.target.value.toLowerCase().trim())
)
);
};
return (
<>
<input
type="text"
name="filter_users"
className={classes.filter_input}
onChange={e => filterUsers(e)}
placeholder="search user..."
autoComplete="off"
/>
<ul>
{filteredUsers.length ? (
filteredUsers.map(user => {
return (
<label key={user.id} htmlFor={user.name}>
<li className={classes.user_container}>
<div className={classes.user_subcontainer}>
<div
className={`${classes.avatar_container} ${
user.gender === 'Male' ? classes.male : classes.female
}`}
>
{user.avatar ? (
<img className={classes.avatar} src={user.avatar} alt="#" />
) : (
<div className={classes.img_alt}>
{user.first_name.slice(0, 1)}
{user.last_name.slice(0, 1)}
</div>
)}
</div>
<h3
className={user.gender === 'Male' ? classes.male_text : classes.female_text}
>
{user.first_name} {user.last_name}
</h3>
</div>
<div className={classes.checkbox_container}>
<input type="checkbox" name={user.id} onChange={e => checkUsers(e)} />
</div>
</li>
</label>
);
})
) : (
<h1 className={classes.list_loading}>List loading...</h1>
)}
</ul>
</>
);
};
解决方案
我在这里讨论了您的代码的一些细节,但希望它演示了如何使用 checked 属性:
const UsersList = ({ users }) => {
const [checkedUsersIds, setCheckedUsersIds] = React.useState([]);
const [filteredUsers, setFilteredUsers] = React.useState([]);
React.useEffect(() => setFilteredUsers(users), [users]);
// React.useEffect(() => console.log(checkedUsersIds), [checkedUsersIds]);
const checkUsers = e => {
if (e.target.checked) {
const checkedUser = users.find(user => user.id === Number(e.target.name));
setCheckedUsersIds([...checkedUsersIds, checkedUser.id]);
} else {
setCheckedUsersIds(checkedUsersIds.filter(user => user !== Number(e.target.name)));
}
};
const filterUsers = e => {
const value = e.target.value.toLowerCase().trim();
setFilteredUsers(
users.filter(
user =>
user.first_name.toLowerCase().includes(value) ||
user.last_name.toLowerCase().includes(value)
)
);
};
return (
<React.Fragment>
<input
type="text"
name="filter_users"
onChange={e => filterUsers(e)}
placeholder="search user..."
autoComplete="off"
/>
<ul>
{ filteredUsers.map(user => {
return (
<li key={user.id}>
<label htmlFor={user.name}>
{user.first_name} {user.last_name}
<input
type="checkbox"
name={user.id}
onChange={e => checkUsers(e)}
checked={checkedUsersIds.includes(user.id)}
/>
</label>
</li>
);
})
}
</ul>
</React.Fragment>
);
};
const App = () =>
<UsersList
users={[
{ id: 1, first_name: 'Harry', last_name: 'Bibbleson' },
{ id: 2, first_name: 'Sally', last_name: 'Refsted' },
{ id: 3, first_name: 'Swonky', last_name: 'Trevor' },
]}
/>;
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
推荐阅读
- c - 函数不在 C 中同时运行
- spring-boot - 通过服务调用时文件上传失败,即restTemplate.postForEntity
- jmeter - PerfMon 指标收集器图显示最多 4 分钟的信息,但脚本执行的实际时间为 10 分钟
- python - 如何在ORACLE表中插入json数据?
- sql - 循环所有表并执行存储过程
- javascript - PHP将文件发送到Web服务器无法访问的浏览器
- jquery - 当您在每个循环中修改 jQuery 集合时,是包含修改后的集合还是仅包含原始集合?
- vue.js - 无法在 vuetify 项目中添加自定义颜色
- git - Git rebase to orphan 导致二进制文件冲突
- c# - 可空值类型上的提升运算符是否使用短路?