【问题标题】:How to handle multiple Checkboxes in a React State: multiple Arrays?如何在 React 状态下处理多个复选框:多个数组?
【发布时间】:2022-02-16 01:03:04
【问题描述】:

伙计们,我刚刚在这里使用了 Shahnawaz 示例 Handle multiple Checkboxed in a State:Array. How to? 但是,当单击具有同一项目的名称/类别时,请遵守多个真实ID,将为您提供重复的Project1和Project2,当检查两个类别时=== true .....

checked1 (english === true) 会给你 project1 , project2 checked2 (maths=== true) 会给你 project1 , project3 再次检查 4 项目 1 ,项目 2 重复

关于如何解决这个问题的任何想法?

import React from "react";

const Checkbox = ({ type = "checkbox", name, checked = false, onChange }) => (
  <input type={type} name={name} checked={checked} onChange={onChange} />
);

const checkboxes = [
  {
    id: "31",
    category: "englsh",
    projects: [
      {
        id: "9",
      },
    ],
  },
  {
    id: "32",
    category: "maths",
    projects: [
      {
        id: "2",
      },
    ],
  },
  {
    id: "33",
    category: "marketing",
    projects: [
      {
        id: "2",
      },
    ],
  },
  {
    id: "34",
    category: "physics",
    projects: [
      {
        id: "2",
      },
    ],
  },
  {
    id: "35",
    category: "media ",
    projects: [
      {
        id: "2",
      },
      {
        id: "10",
      },
    ],
  },
  {
    id: "36",
    category: "science",
    projects: [
      {
        id: "9",
      },
      {
        id: "11",
      },
    ],
  },
];

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      checkedItems: new Map(),
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const item = e.target.name;
    const isChecked = e.target.checked;
    console.log(item);
    console.log(isChecked);
    this.setState((prevState) => ({
      checkedItems: prevState.checkedItems.set(item, isChecked),
    }));
  }

  render() {
    return (
      <div className="row float-center d-flex justify-content-center">
        {checkboxes.map((item) => (
          <label key={item.key} className="m-3">
            <Checkbox
              name={item.name}
              checked={this.state.checkedItems.get(item.name)}
              onChange={this.handleChange}
            />
            {item.name}
          </label>
        ))}
      </div>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    如果您希望标签上显示name 下的密钥,请通过执行此Object.keys(item.name)[0] 而不是item.name 来提取您的密钥。此外,传递一个额外的属性(此处为index),以便您可以通过正确的索引从checkboxes 数组中打印所需的值。在这里,我使用event.target 完成了这项工作。

    Update:

    如果您想要唯一的值,只需声明一个状态,以便您可以将项目添加到该数组(选中时)并从该数组中删除项目(未选中时)。最后,把你的数组放在一个集合中,你就完成了。使用Array.from() 将集合转换为数组。

    这是工作代码:

    import React from "react";
    
    const Checkbox = ({
      type = "checkbox",
      name,
      index,
      checked = false,
      onChange,
    }) => (
      <input
        type={type}
        name={name}
        data-index={index}
        checked={checked}
        onChange={onChange}
      />
    );
    
    const checkboxes = [
      {
        name: { english: ["project1", "project2"] },
        key: "1",
        label: "1",
      },
      {
        name: { maths: ["project1", "project3"] },
        key: "2",
        label: "2",
      },
      {
        name: { physics: ["project4", "project5"] },
        key: "3",
        label: "3",
      },
      {
        name: { marketing: ["project1", "project2"] },
        key: "4",
        label: "4",
      },
    ];
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          checkedItems: new Map(),
          checkedArrays: [],
        };
    
        this.handleChange = this.handleChange.bind(this);
      }
    
      handleChange(e) {
        const item = e.target.name;
        const isChecked = e.target.checked;
        let [key, value] = Object.entries(
          checkboxes[e.target.dataset.index].name
        )[0];
        console.log(isChecked);
        console.log(key);
        var len = value.length;
    
        if (isChecked) {
          for (var i = 0; i < len; i++) {
            this.state.checkedArrays.push(value[i]);
          }
        } else {
          for (var i = 0; i < len; i++) {
            const index = this.state.checkedArrays.indexOf(value[i]);
            if (index > -1) {
              this.state.checkedArrays.splice(index, 1); // 2nd parameter means remove one item only
            }
          }
        }
    
        this.setState((prevState) => ({
          checkedItems: prevState.checkedItems.set(item, isChecked),
        }));
    
        console.log("Duplicated array");
        console.log(this.state.checkedArrays);
        var uniqueArray = Array.from(new Set(this.state.checkedArrays));
        console.log("Unique array");
        console.log(uniqueArray);
      }
    
      render() {
        return (
          <div className="row float-center d-flex justify-content-center">
            {checkboxes.map((item, index) => (
              <label key={item.key} className="m-3">
                <Checkbox
                  name={Object.keys(item.name)[0]}
                  index={index}
                  checked={this.state.checkedItems.get(Object.keys(item.name)[0])}
                  onChange={this.handleChange}
                />
                {Object.keys(item.name)[0]}
              </label>
            ))}
          </div>
        );
      }
    }
    

    2nd update based on the requirements

    import React from "react";
    
    const Checkbox = ({
      type = "checkbox",
      name,
      index,
      checked = false,
      onChange,
    }) => (
      <input
        type={type}
        name={name}
        data-index={index}
        checked={checked}
        onChange={onChange}
      />
    );
    
    const checkboxes = [
      {
        id: "31",
        category: "englsh",
        projects: [
          {
            id: "9",
            title: "This is the title for id 9",
            description: "This is description for id 9",
          },
        ],
      },
      {
        id: "32",
        category: "maths",
        projects: [
          {
            id: "2",
            title: "This is the title for id 2",
            description: "This is description for id 2",
          },
        ],
      },
      {
        id: "33",
        category: "marketing",
        projects: [
          {
            id: "2",
            title: "This is the title for id 2",
            description: "This is description for id 2",
          },
        ],
      },
      {
        id: "34",
        category: "physics",
        projects: [
          {
            id: "2",
            title: "This is the title for id 2",
            description: "This is description for id 2",
          },
        ],
      },
      {
        id: "35",
        category: "media",
        projects: [
          {
            id: "2",
            title: "This is the title for id 2",
            description: "This is description for id 2",
          },
          {
            id: "10",
            title: "This is the title for id 10",
            description: "This is description for id 10",
          },
        ],
      },
      {
        id: "36",
        category: "science",
        projects: [
          {
            id: "9",
            title: "This is the title for id 9",
            description: "This is description for id 9",
          },
          {
            id: "11",
            title: "This is the title for id 11",
            description: "This is description for id 11",
          },
        ],
      },
    ];
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          checkedItems: new Map(),
          checkedArrays: [],
        };
    
        this.handleChange = this.handleChange.bind(this);
      }
    
      handleChange(e) {
        const item = e.target.name;
        const isChecked = e.target.checked;
        let value = Object.values(checkboxes[e.target.dataset.index].projects);
        console.log(isChecked);
        console.log(item);
        var len = value.length;
    
        if (isChecked) {
          for (var i = 0; i < len; i++) {
            this.state.checkedArrays.push(value[i]);
          }
        } else {
          for (var i = 0; i < len; i++) {
            let index = this.state.checkedArrays.findIndex(
              (x) => x.id === value[i].id
            );
            if (index > -1) {
              this.state.checkedArrays.splice(index, 1); // 2nd parameter means remove one item only
            }
          }
        }
    
        this.setState((prevState) => ({
          checkedItems: prevState.checkedItems.set(item, isChecked),
        }));
    
        console.log("Duplicated array");
        console.log(this.state.checkedArrays);
    
        var uniqueArray = this.state.checkedArrays.filter(function (elem) {
          return !this[elem.id] && (this[elem.id] = true);
        }, Object.create(null));
    
        console.log("Unique array");
        console.log(uniqueArray);
      }
    
      render() {
        return (
          <div className="row float-center d-flex justify-content-center">
            {checkboxes.map((item, index) => (
              <label key={item.id} className="m-3">
                <Checkbox
                  name={item.category}
                  index={index}
                  checked={this.state.checkedItems.get(item.category)}
                  onChange={this.handleChange}
                />
                {item.category}
              </label>
            ))}
          </div>
        );
      }
    }
    

    【讨论】:

    • 太棒了,这是一个完美的解决方案。再次感谢您的时间和支持。
    • 这是我的荣幸 :)
    猜你喜欢
    • 2020-03-24
    • 1970-01-01
    • 2021-10-01
    • 2018-03-18
    • 1970-01-01
    • 2022-01-14
    • 2020-12-21
    • 2015-10-01
    • 1970-01-01
    相关资源
    最近更新 更多