簡體   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