首页 > 解决方案 > 如何在 ReactJS 中使用 Checkbox 制作树复选框列表?

问题描述

我曾经从三个细分中创建一个带有复选框的树结构。但是,当我们在我创建的结构中选择上层单元时,它必须选择所有子单元,但是在这个结构中是不可能的。我怎样才能在递归和树逻辑中做到这一点。

const CheckBoxTree = (props) => {
  const itemOptions = props.options;
  const [checkedItems, setCheckedItems] = useState(itemOptions);
  const [selectedValues, setSelectedValues] = useState({ selectedItem: [] });
  const [isPropReady, setIsPropReady] = useState(false);

  const chekboxIdCode = (name) => {
    return props.id + name;
  };
  useEffect(() => {
    if (props.value.length > 0 && !isPropReady) {
      selectedValues.selectedItem = props.value;
      props.value.forEach((item, i) => {
        const id = chekboxIdCode(item);
        setCheckedItems((checkedItems) => ({ ...checkedItems, [id]: true }));
      });
      setIsPropReady(true);
    }
  }, [props.value]);

  useEffect(() => {
    let target = {
      id: props.id,
      name: props.id,
      value: selectedValues.selectedItem,
    };
    props.onClick(target);
  }, [selectedValues.selectedItem]);

  const handleChange = (event,sellector) => {
    const id = event.target.id;
    const checked = event.target.checked;
    const value = parseInt(event.target.value);
    setCheckedItems({
      ...checkedItems,
      [id]: checked,
    });
    if (checked) {
      setSelectedValues({
        selectedItem: [...selectedValues.selectedItem, value],
      });
    } else {
      let remove = selectedValues.selectedItem.indexOf(value);
      setSelectedValues({
        selectedItem: selectedValues.selectedItem.filter(
          (_, i) => i !== remove
        ),
      });
    }
  };
  return (
    <div className={"col-md-12"}>
      {props.error && (
        <label
          id={props.name + "-error"}
          className="error-label mb-3"
          htmlFor={props.name}
        >
          {props.error}
        </label>
      )}
      <ul className={"list-menu"}>
        {itemOptions.map((option,index_1) => (
          <li key={chekboxIdCode(option[props.optionValue])}>
            <CheckBox
              id={chekboxIdCode(option[props.optionValue])}
              checked={checkedItems[chekboxIdCode(option[props.optionValue])]}
              label={option[props.optionLabel]}
              onClick={(e)=>handleChange(e,`[${index_1}]`)}
              className={"col-md-12 pt-1 pb-1"}
              value={option[props.optionValue]}
            />
            <ul>
              {option.content &&
                option.content.map((subOptionOne,index_2) => {
                  return (
                    <li key={chekboxIdCode(subOptionOne[props.optionValue])}>
                      <CheckBox
                        id={chekboxIdCode(subOptionOne[props.optionValue])}
                        checked={
                          checkedItems[
                            chekboxIdCode(subOptionOne[props.optionValue])
                          ]
                        }
                        label={subOptionOne[props.optionLabel]}
                        onClick={(e)=>handleChange(e,`[${index_1}]["content"][${index_2}]`)}
                        className={"col-md-12 pt-1 pb-1"}
                        value={subOptionOne[props.optionValue]}
                      />
                      {subOptionOne.content &&
                        subOptionOne.content.map((subOptionTwo,index_3) => {
                          return (
                            <li
                              key={chekboxIdCode(
                                subOptionTwo[props.optionValue]
                              )}
                              className="ml-4"
                            >
                              <CheckBox
                                id={chekboxIdCode(
                                  subOptionTwo[props.optionValue]
                                )}
                                checked={
                                  checkedItems[
                                    chekboxIdCode(
                                      subOptionTwo[props.optionValue]
                                    )
                                  ]
                                }
                                label={subOptionTwo[props.optionLabel]}
                                onClick={(e)=>handleChange(e,`[${index_1}]["content"][${index_2}]["content"][${index_3}]`)}
                                className={"col-md-12 pt-1 pb-1"}
                                value={subOptionTwo[props.optionValue]}
                              />
                            </li>
                          );
                        })}
                    </li>
                  );
                })}
            </ul>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default CheckBoxTree;

我不想在这个结构中使用组件。为此,我想创建自己的组件,您能在这个方向上提出您的解决方案建议吗?

标签: reactjscheckboxtree

解决方案


推荐阅读