通过 React 挂钩/功能组件根据子组件中检查的输入填充父数组

Populate array in parent based on checked inputs in child component via React hooks / functional components

我有一个呈现类别列表的父组件。每个列表项都包含一个子组件 Checkbox,其中包含一个复选框输入。

在父组件中,我需要一个数组,其中包含选中的复选框输入的 ID。如果未选中复选框,则应从数组中删除 ID。

在 Checkbox 组件中,handleChange 功能有效,但我还需要以某种方式将数据发送给父项。我猜我需要某种回调函数吗?

如何访问父组件中选中输入的 ID?

到目前为止我的代码:

父组件:

import {useState} from "react";

import Checkbox from "../functions/Checkbox.js";

function CategoryList() {

    const categories = ['CategoryA','CategoryB', 'CategoryC']

    const [checkedCategories, setCheckedCategories] = useState([]);

    return(
        <ul>
            {categories.map(categories =>
                 <li key={categories.toLowerCase()}>
                     <Checkbox id={categories.toLowerCase()}
                               label={categories}
                     />
                             
                </li>
            )}
        </ul>
    )
}

export default CategoryList;

子组件:


function Checkbox(props) {

   const [checked, setChecked] = useState(false);

   const checkboxId = props.id;
   const checkboxLabel = props.label;

   const handleChange = () => {

       setChecked(!checked);
       console.log('changed value of checkbox');

   }

    return(
        <label htmlFor={checkboxId} >
            <input type="checkbox"
                   name="category-input"
                   id={checkboxId}
                   onChange={handleChange}
            />
            {checkboxLabel}
        </label>

    );
}

export default Checkbox;

function CategoryList() {
  const categories = ["CategoryA", "CategoryB", "CategoryC"];

  const [checkedCategories, setCheckedCategories] = useState([]);

  const checkboxChanged = (id) => {
    console.log(id);
  };

  return (
    <ol>
      {categories.map((categories) => (
        <li key={categories.toLowerCase()}>
          <Checkbox
            id={categories.toLowerCase()}
            label={categories}
            checkboxChanged={checkboxChanged}
          />
        </li>
      ))}
    </ol>
  );
}

props.checkboxChanged 将复选框的 id 发送到已更改的父组件

function Checkbox(props) {
  const [checked, setChecked] = useState(false);

  const checkboxId = props.id;
  const checkboxLabel = props.label;

  const handleChange = () => {
    setChecked(!checked);
    console.log("changed value of checkbox");

    props.checkboxChanged(checkboxId); // will send id back to parent component
  };

  return (
    <label htmlFor={checkboxId}>
      <input
        type="checkbox"
        name="category-input"
        id={checkboxId}
        onChange={handleChange}
      />
      {checkboxLabel}
    </label>
  );
}



我认为对于这种情况,您需要操作对象而不仅仅是字符串,因为您将同时存储 labelchecked 值。

下面的代码更合适

import React, { useEffect, useState } from 'react';

import Checkbox from "../functions/Checkbox.js";

function CategoryList() {

    const categories = [{ label: 'CategoryA', checked: false }, { label: 'CategoryB', checked: false }, { label: 'CategoryC', checked: false }];

    const [checkedCategories, setCheckedCategories] = useState([]);
    // Keeps your array of selected categories constantly updated
    useEffect(() => {
        const categoriesFilter = categories.filter(category => category.checked);
        setCheckedCategories(categoriesFilter);
    }, [categories]);

    return (
        <ol>
            {categories.map(category =>
                <li key={category.label.toLowerCase()}>
                    <Checkbox id={category.label.toLowerCase()} data={category} />
                </li>
            )}
        </ol>
    )
}

export default AllBots();
function Checkbox({ id: checkboxId, data: category }) {

    return (
        <label htmlFor={checkboxId} >
            <input type="checkbox"
                name="category-input"
                id={checkboxId}
                onChange={() => category.checked = !category.checked}
            />
            {category.label}
        </label>
    );
}

export default Checkbox;

我想你可以通过函数来​​更新你选中的类别。 使用你的 id 的小写版本,它应该是这样的:

父组件:

function CategoryList() {

  const categories = ['CategoryA','CategoryB', 'CategoryC']
  const [checkedCategories, setCheckedCategories] = useState([]);

  const addToCheckedCategories = id => {
    const updatedCheckedCategories = [...checkedCategories];
    updatedCheckedCategories.push(id);
    setCheckedCategories(updatedCheckedCategories);
  };

  const removeFromCheckedCategories = id => {
    const updatedCheckedCategories = checkedCategories.filter(cat => cat !== id);
    setCheckedCategories(updatedCheckedCategories);
  };

  return(
      <ul>
        {categories.map(categories =>
             <li key={categories.toLowerCase()}>
                 <Checkbox id={categories.toLowerCase()}
                           label={categories}
                           addToCheckedCategories={addToCheckedCategories}
                           removeFromCheckedCategories={removeFromCheckedCategories}
                 />
            </li>
        )}
      </ul>
  );
}

子组件:

function Checkbox(props) {

   const [checked, setChecked] = useState(false);

   const checkboxId = props.id;
   const checkboxLabel = props.label;
   const addToCheckedCategories = props.addToCheckedCategories;
   const removeFromCheckedCategories = props.removeFromCheckedCategories;

   const handleChange = id => {

       if (checked) {
         removeFromCheckedCategories(id);
       } else {
         addToCheckedCategories(id);
       }
       setChecked(!checked);
       console.log('changed value of checkbox');

   }

    return(
        <label htmlFor={checkboxId} >
            <input type="checkbox"
                   name="category-input"
                   id={checkboxId}
                   onChange={() => handleChange(checkboxId)}
            />
            {checkboxLabel}
        </label>
    );
}

export default Checkbox;

如果有帮助请告诉我!