繁体   English   中英

如何将 React 组件的自定义钩子与“map”一起使用

[英]How to use React component's custom hook with “map”

我正在尝试制作一个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组件,我必须将此Listdata一起使用。

const Home = ({data}) => {
  return (
    <Layout>
      {data.map((d) => <List />)}
    </Layout>
  );
};

在这种情况下,有没有办法确定列表是否被选中?

如果ListuseCheckbox ,则Home组件不知道checked的 state。

我应该在Home组件中使用useCheckbox来获取data.length时间吗? 我认为这不好。

感谢阅读,新年快乐。

如果您希望复选框 state 存在于Home级别,那么您需要Home组件中的 state 可以处理多个项目,可以作为数组或 object。

然后,在 map 的data上,您可以将checkedsetChecked作为道具传递给List ,使用与Home state 相关的项目索引(或者最好是 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>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM