【问题标题】:How to use React component's custom hook with "map"如何将 React 组件的自定义钩子与“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 组件,我必须将此Listdata 一起使用。

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

这种情况下,有没有办法判断列表是否被选中?

如果List 具有useCheckbox,则Home 组件不知道checked 状态。

我应该在Home 组件中使用useCheckbox data.length 次吗?我觉得这样不好。

感谢阅读,新年快乐。

【问题讨论】:

  • 为什么你有两个同名的组件? - 您的代码很好,但您需要在 map() 函数上使用数据之前检查数据是否实际存在。类似于 data.length > 0 && data.map()

标签: javascript reactjs react-hooks components state


【解决方案1】:

如果您希望复选框状态存在于Home 级别,那么您需要Home 组件中的状态,该状态可以处理多个项目,可以是数组或对象。

然后,在您映射 data 的位置,您可以将 checkedsetChecked 作为道具传递给 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>
  );
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2020-01-18
    • 2019-06-22
    • 2021-02-15
    相关资源
    最近更新 更多