首页 > 解决方案 > 如何在反应中使函数动态化?

问题描述

我可以创建一个包含多个复选框的列表并选择所有选项。感谢这个答案 现在我需要使这个handleChange函数动态化,以便我可以将此函数重用于多个状态列表。任何帮助,将不胜感激。

this.state = {
list1: [
        { name: "item1", isChecked: true },
        { name: "item2", isChecked: true },
        { name: "item3", isChecked: true }
      ]
    };
<input
          type="checkbox"
          name="checkAll"
          checked={this.state.allChecked}
          onChange={(e) => this.handleChange(e, 'list1')}
/>
handleChange = (e, listName) => {
    let itemName = e.target.name;
    let checked = e.target.checked;
    this.setState((prevState) => {
      let { list1, allChecked } = prevState;
      if (itemName === "checkAll") {
        allChecked = checked;
        list1 = [listName].map((item) => ({ ...item, isChecked: checked }));
      } else {
        list1 = [listName].map((item) =>
          item.name === itemName ? { ...item, isChecked: checked } : item
        );
        allChecked = [listName].every((item) => item.isChecked);
      }
      return { list1, allChecked };
    });
  };

标签: reactjs

解决方案


您将列表 ID 传递给handleChange函数是正确的。唯一缺少的是通过 id 获取列表并更新其项目。

handleChange = (e, listId) => {
  let itemName = e.target.name
  let checked = e.target.checked

  this.setState((prevState) => {
    const { lists } = prevState
    const list = lists[listId]
    if (itemName === 'checkAll') {
      lists[listId] = list.map((item) => ({
        ...item,
        isChecked: checked,
      }))
    } else {
      lists[listId] = list.map((item) =>
        item.name === itemName ? { ...item, isChecked: checked } : item
      )
    }
    return { lists }
  })
}

而且您不必allChecked在该州进行跟踪。可以使用 来计算list.every((item) => item.isChecked)

方法render变成

const { lists } = this.state
return (
  <div>
    {Object.keys(this.state.lists).map((listId) => {
      const list = lists[listId]
      const allChecked = list.every((item) => item.isChecked)
      return (
        <div className="list" key={listId}>
          <input
            type="checkbox"
            name="checkAll"
            checked={allChecked}
            onChange={(e) => this.handleChange(e, listId)}
          />
          Check all
          <br />
          {list.map((item) => (
            <div key={`${listId}-${item.name}`}>
              <input
                type="checkbox"
                name={item.name}
                value={item.name}
                checked={item.isChecked}
                onChange={(e) => this.handleChange(e, listId)}
              />
              <label>{item.name}</label>
            </div>
          ))}
        </div>
      )
    })}
  </div>
)

代码沙盒


推荐阅读