如何将 React 组件的自定义钩子与“map”一起使用
Posted
技术标签:
【中文标题】如何将 React 组件的自定义钩子与“map”一起使用【英文标题】:How to use React component's custom hook with "map" 【发布时间】:2021-04-07 21:51:04 【问题描述】:我正在尝试制作一个Checkbox
组件。
这是我的Checkbox.tsx
。
import React from "react";
import * as S from "./style";
const Checkbox: React.FC<S.ICheckboxProps> = ( checked, setChecked ) =>
return <S.StyledCheckbox checked=checked onClick=setChecked />;
;
这是我的useCheckbox.tsx
,
import useState from "react";
export const useCheckbox = (initialState: boolean) =>
const [checked, _setChecked] = useState<boolean>(initialState);
const setCheckedToggle = () => _setChecked((prev) => !prev);
const setCheckedTrue = () => _setChecked(true);
const setCheckedFalse = () => _setChecked(false);
return checked, setCheckedToggle, setCheckedTrue, setCheckedFalse ;
;
export default Checkbox;
效果很好。我可以这样使用
import Layout from "components/Layout";
import useCheckbox from "hooks/useCheckbox";
import Checkbox from "components/Checkbox";
const Home = () =>
const checked, setCheckedToggle = useCheckbox(false);
return (
<Layout>
<Checkbox checked=checked setChecked=setCheckedToggle />
</Layout>
);
;
export default Home;
但我在List
组件中遇到了问题。
List
有一个Checkbox
组件,我必须将此List
与data
一起使用。
const Home = (data) =>
return (
<Layout>
data.map((d) => <List />)
</Layout>
);
;
这种情况下,有没有办法判断列表是否被选中?
如果List
具有useCheckbox
,则Home
组件不知道checked
状态。
我应该在Home
组件中使用useCheckbox
data.length
次吗?我觉得这样不好。
感谢阅读,新年快乐。
【问题讨论】:
为什么你有两个同名的组件? - 您的代码很好,但您需要在 map() 函数上使用数据之前检查数据是否实际存在。类似于 data.length > 0 && data.map() 【参考方案1】:如果您希望复选框状态存在于Home
级别,那么您需要Home
组件中的状态,该状态可以处理多个项目,可以是数组或对象。
然后,在您映射 data
的位置,您可以将 checked
和 setChecked
作为道具传递给 List
,并使用项目索引在 Home
中定义的所有逻辑(或者最好使用 ID,如果有一)与您的Home
状态有关。
这是一个可以在 Home
中使用的钩子示例
import useState from "react";
export const useCheckboxes = () =>
const [checkedIds, setCheckedIds] = useState([]);
const addToChecked = (id) => setCheckedIds((prev) => [...prev, id]);
const removeFromChecked = (id) =>
setCheckedIds((prev) => prev.filter((existingId) => existingId !== id));
const isChecked = (id) => !!checkedIds.find(id);
const toggleChecked = (id) =>
isChecked(id) ? removeFromChecked(id) : addToChecked(id);
return isChecked, toggleChecked ;
;
你会这样使用它
const Home = ( data ) =>
const isChecked, toggleChecked = useCheckboxes();
return (
<Layout>
data.map((d) => (
<List
key=d.id
checked=isChecked(d.id)
toggleChecked=() => toggleChecked(d.id)
/>
))
</Layout>
);
;
【讨论】:
以上是关于如何将 React 组件的自定义钩子与“map”一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JEST、Enzyme 在 React 中测试自定义钩子?
使用钩子将 React Context 与 AsyncStorage 结合使用
为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?
如何将 React 钩子(useContext、useEffect)与 Apollo 反应钩子(useQuery)结合起来