javascript - 过滤后返回处于 React 状态的对象的正确长度
问题描述
我是 React 的新手,并且一直在开发这个功能,其中有一个过滤选项,用户在输入中键入他正在寻找的用户的姓名或电子邮件,并且列表会随着输入的变化而更新。
当组件加载时,useEffect
hook 从我的 api 中获取数据并将返回设置为我的状态,并且在过滤器输入中键入的数据也保存在状态中。
我在打字时的过滤效果很好,filter
旁边的map
效果很好,并且只列出了我正在寻找的用户。
我的问题是,当组件加载时,它还会显示找到了多少用户,现在我只列出组件安装时的数组长度,所以我的问题是:
如何在users
不破坏状态的情况下更新数组长度的大小?如果我在我的状态中设置过滤后的数组,并且在删除查询字符串后,我的状态将被破坏......我尝试使用过滤结果创建另一个状态但没有工作,还有另一种更好的方法或者我做错了什么?
<ContentSearchReturn section="Mentores" qtdUsers={users.length} />
Mentors
呈现页面ListMentors
的组件,并且是呈现我的每个 Evee 盒子的组件。
const Mentors = () => {
const formRef = useRef(null);
const [users, setUsers] = useState([]);
const [filter, setFilter] = useState(null);
useEffect(() => {
const fetchUsers = async () => {
const { data } = await api.get("/colaborador/mentores");
setUsers(data);
};
fetchUsers();
}, []);
return (
<Layout>
<BodyContent
header="Gerenciamento de Mentores"
breadcrumb="Home > Mentores"
>
<Form ref={formRef} style={{ marginBottom: "3vh" }}>
<Row>
<Col lg="8" style={{ backgroundColor: "" }}>
<FormGroup>
<Input
label="Informe o nome ou e-mail do mentor"
name="pesquisa"
testid="fieldPesquisarColaborador"
style={{ marginTop: "0", marginBottom: "0" }}
onChange={(e) => setFilter(e.target.value)}
/>
</FormGroup>
</Col>
<Col lg={{ size: 3, offset: 1 }} style={{ backgroundColor: "" }}>
<Button
text="Cadastrar"
onClick={() => history.push("/admin/create-collaborator")}
style={{ width: "100%" }}
/>
</Col>
</Row>
</Form>
<ListMentors users={users} filter={filter} />
</BodyContent>
</Layout>
);
};
export default Mentors;
ListMentors
组件并且qtdUsers
是在上面打印中显示 7 个结果的道具。
const ListMentors = ({ users, filter }) => {
return (
<>
<ContentSearchReturn section="Mentores" qtdUsers={users.length} />
<Row>
{users.length > 0 ? (
users
.filter((user) => {
if (!filter) return true;
if (user.nome.includes(filter) || user.email.includes(filter)) {
return true;
}
})
.map((user, index) => {
return (
<UserBox
key={index}
nome={user.nome}
cargo={user.nome_cargo}
departamento={user.nome_departamento}
/>
);
})
) : (
<div>
<h1>Ops! 0 resultados...</h1>
</div>
)}
</Row>
</>
);
};
export default ListMentors;
非常感谢您的宝贵时间,并为我的英语感到抱歉,这里不是母语人士。
解决方案
您可以使用useMemo
来存储过滤后的用户数组。
然后filteredUser.length
将始终是过滤后数组的大小(或整个数组的!filter
大小true
)
请注意,派生值将仅在users
或filter
更改时计算。
const ListMentors = ({users, filter}) => {
const filteredUsers = useMemo(() => {
return users.filter((user) => {
if (!filter) return true;
if (user.nome.includes(filter) || user.email.includes(filter)) {
return true;
}
});
}, [users, filter]);
return (
<>
<ContentSearchReturn section="Mentores" qtdUsers={filteredUsers.length} />
<Row>
{filteredUsers.length > 0 ? (
filteredUsers.map((user, index) => {
return (
<UserBox
key={index}
nome={user.nome}
cargo={user.nome_cargo}
departamento={user.nome_departamento}
/>
);
})
) : (
<div>
<h1>Ops! 0 resultados...</h1>
</div>
)}
</Row>
</>
);
};
export default ListMentors;
PS。
const filteredUsers = users.filter((user) => {
if (!filter) return true;
if (user.nome.includes(filter) || user.email.includes(filter)) {
return true;
}
});
不使用useMemo
也应该可以正常工作,但它会导致您在每次渲染时重新计算过滤后的数组。
推荐阅读
- kubernetes - 我可以使用从 pod 中的 init 容器创建的配置映射吗
- datastax-enterprise - 使用 DSE 高级复制与手动多 DC 设置进行灾难恢复之间的区别?
- spring - Spring Boot端口转发80到8080
- rotation - 如何围绕自身边界的中心旋转 UIBezierPath?
- r - 在 ggplot2 中绘制 shapefile:Print() 错误
- java - 异常处理,第一个 try/catch 块在接受正确输入之前不会重复
- google-cloud-stackdriver - 在 StackDriver 中跨 Google Cloud 中的多个项目设置基于日志的警报
- javascript - 与锚一起使用的滚动魔术针
- c++ - SDL2 C++ 未处理异常
- jqgrid - jqGrid,复选框未在编辑表单上左对齐。引导程序