简体   繁体   English

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

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

I'm trying to make a Checkbox component.我正在尝试制作一个Checkbox组件。

Here is my Checkbox.tsx .这是我的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} />;
};

and this is my useCheckbox.tsx ,这是我的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;

It works good.它运作良好。 I can use this like我可以像这样使用

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;

But I have trouble in the List component.但是我在List组件中遇到了麻烦。

List has a Checkbox component, and I have to use this List with data . List有一个Checkbox组件,我必须将此Listdata一起使用。

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

In this case, is there a way to determine if the list is selected?在这种情况下,有没有办法确定列表是否被选中?

If the List has useCheckbox , the Home component doesn't know the checked state.如果ListuseCheckbox ,则Home组件不知道checked的 state。

Should I use useCheckbox in the Home component for data.length times?我应该在Home组件中使用useCheckbox来获取data.length时间吗? I think this is not good.我认为这不好。

Thanks for reading, and Happy new year.感谢阅读,新年快乐。

If you want the checkbox state to exist at the level of Home then you'll need state in the Home component that can handle multiple items, either as an array or object.如果您希望复选框 state 存在于Home级别,那么您需要Home组件中的 state 可以处理多个项目,可以作为数组或 object。

Then where you map over data you can pass down checked and setChecked as props to List , with all the logic defined in Home using the item index (or preferably an ID if you have one) in relation to your Home state.然后,在 map 的data上,您可以将checkedsetChecked作为道具传递给List ,使用与Home state 相关的项目索引(或者最好是 ID,如果有的话)在Home中定义所有逻辑。

Here's an example of a hook you could use in 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 };
};

And you would use it like this你会像这样使用它

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