javascript - 选择或取消选择复选框 - ReactJS

标签 javascript reactjs material-ui

我已经成功创建了选择单个或多个框的函数。在单个选项上我没有任何问题,我的意思是当您单击一个框时,它会被选中或取消选中。

但与全选的情况不一样。有什么想法可以解决这个问题吗? (我在我的盒子中使用 material-ui 库,但基本上它们是简单的 HTML 输入)

选择所有组件和功能:

<Checkbox
    name="checkboxes"
    checked={this.state.allCheckboxes}
    onChange={this.handleAllCheckboxes}
    indeterminate
    />Select All

功能:

handleAllCheckboxes = (e) => {
    let responseObj = this.state.items;
    let prepareObj = {};
    if(e.target.checked){
        //to do add loop to check all check box
        responseObj.forEach(function(item){
            if(item.documentId !== null && item.documetNumber !== null ){
                prepareObj[item.documentId] = item.documentNumber;
                // this.refs.documentId
            }
        });
        let toSee = Object.keys(prepareObj).length > 0 ? true : false;
        this.setState({
            docList: prepareObj,
            visible: toSee
        })
        let checkboxes = document.getElementsByName('DocCheckbox')
        checkboxes.forEach(function(checkbox){
            checkbox.checked = checkbox.checked
            })
            console.log(checkboxes)
    } else {
        //to do add loop to uncheck all check box
        this.setState({
            prepareObj: {}
        })
    }

    console.log(prepareObj);

};

选择单个组件和功能:

<Checkbox
      name='DocCheckbox'
      type='checkbox'
      color='default'
      value={JSON.stringify({ documentId: rowData.documentId, documentNumber: rowData.documentNumber })}
      onClick={this.handleCheckboxClick}/>

功能:

handleCheckboxClick = (e, id) => {

    if (id) {


    } else {
        let parsedVal = JSON.parse(e.target.value);
        // console.log(e.target.value)
        let newDocList = { ...this.state.docList };
        if (e.target.checked) {
            this.setState({
                singleCheckbox:true
            })
            newDocList[parsedVal.documentId] = parsedVal.documentNumber;
        } else {
            delete newDocList[parsedVal.documentId];
            this.setState({
                singleCheckbox:false
            })
        }
        let toSee = Object.keys(newDocList).length > 0 ? true : false;
        this.setState(
            {
                docList: newDocList,
                visible: toSee
            },
            () => {
                console.log(this.state.docList);
            }
        );

    }
};

更新 我的代码的答案基于@norbitrial的回复 (答案基于我的属性、调用和数据,因此请随意根据您的目的进行修改)

第 1 步 - 创建一个构造函数来维护数据和全局检查状态

 constructor(props) {
        super(props);
        this.state = { 
            docList: {},
            checked: false,
            hasToCheckAll: false
       }
    }

第 2 步 - 创建函数来处理单个和多个复选框

处理单个复选框

   handleCheckboxClick = (clickedItem) => {
        console.log(clickedItem)
        // let parsedVal = JSON.parse(e.target.value);
        let newDocList = { ...this.state.docList };
        if (!clickedItem.checked) {
            newDocList[clickedItem.documentId] = clickedItem.documentNumber;
            console.log(newDocList)
        } else {
            delete newDocList[clickedItem.documentId];
        }
        let toSee = Object.keys(newDocList).length > 0 ? true : false;
        console.log(toSee)
        this.setState(
            {
                docList: newDocList,
                visible: toSee
            }, ()=>{
                console.log(newDocList)
            });

        const updatedArray = this.state.items.map((item) => {
            item.checked = item.documentId === clickedItem.documentId ? !item.checked : item.checked;
            return item;
        });

        this.setState({

            items: updatedArray,
        });
    };

处理所有复选框

  handleAllCheckboxes = (e) => {
        const hasToCheckAll = !this.state.hasToCheckAll;
        const updatedArray = this.state.items.map((item) => {
            item.checked = hasToCheckAll;
            return item;
        });
        console.log(updatedArray)

        let responseObj = this.state.items;
        let prepareObj = {};
        if (e.target.checked) {
            //to do add loop to check all check box
            responseObj.forEach(function (item) {
                if (item.documentId !== null && item.documetNumber !== null) {
                    prepareObj[item.documentId] = item.documentNumber;

                }
            });
            let toSee = Object.keys(prepareObj).length > 0 ? true : false;
            console.log(toSee)
            this.setState({
                docList: prepareObj,
                // allCheckboxes: true,
                items: updatedArray,
                hasToCheckAll,
                visible: toSee
            })
            let checkboxes = document.getElementsByName('checkAll')
            checkboxes.forEach(function (checkbox) {
                checkbox.checked = e.target.checked

            })
            console.log(checkboxes)
        } else {
            console.log(updatedArray)
            this.setState({
                docList: {},
                hasToCheckAll:false
            })

        }
    };

第 3 步 - 将内部选中框的状态插入到对象中。并循环它们(这又来 self 后端的响应,因此对于每个人来说,这一步都会有所不同)

  .then((response) => {
                // handle success

                let dataItem = response.data.bills;
                let prepareDataItem = [];
                dataItem.forEach(function (item) {
                    item.checked = false;
                    prepareDataItem.push(item);
                })

第 4 步 - 渲染复选框(这些复选框基于 material-ui 库,但它也适用于简单的输入)

 <Checkbox
       name='DocCheckBox'
       type='checkbox'
       checked={rowData.checked}
       color='default'
       value={JSON.stringify({ documentId: rowData.documentId, documentNumber: rowData.documentNumber })}
       onChange={() => this.handleCheckboxClick(rowData)}/>


   <Checkbox
        name="checkboxes"
        checked={this.state.hasToCheckAll}
        onChange={this.handleAllCheckboxes}
        indeterminate
        />Select All

最佳答案

我会稍微改变一下您在应用程序中处理这些事情的方式。

从技术上讲,您是直接操作 DOM,而不是将其留给 React 处理其状态。在这种情况下,肯定有更好的方法来处理 UI 中的复选框状态。

解决方案:

<强>1。更改默认状态:

让我声明一下,我没有您所拥有的真实数据结构,因此我在构造函数中有以下内容仅用于表示:

constructor(props:any) {
    super(props);
    this.state = {
        items: [
            { documentId: 1, documentNumber: 1234, checked: false },
            { documentId: 2, documentNumber: 1235, checked: false },
            { documentId: 3, documentNumber: 1236, checked: false },
        ],
        hasToCheckAll: false,
    }
}

正如您所看到的,这些项目具有 checked 属性,以便在状态中处理它们。

<强>2。以不同方式呈现复选框

在渲染函数中我改变了几件事:

render() {
    return (
        <div>
            <Checkbox
                name="checkboxes"
                checked={this.state.hasToCheckAll}
                onChange={() => this.handleAllCheckboxes()}
                indeterminate
                />Select All

            {this.state.items.map((item:any) => {
                return <div key={item.documentNumber}>
                    <Checkbox
                        name="DocCheckbox"
                        color="default"
                        checked={item.checked}
                        value={JSON.stringify({ ...item.documentId, ...item.documentNumber })}
                        onChange={() => this.handleCheckboxClick(item)}/> {item.documentNumber}
                </div>
            })}
    </div>
    )
}

<强>3。处理复选框状态也发生了变化:

看看以下处理程序:

handleAllCheckboxes = () => {
    const hasToCheckAll = !this.state.hasToCheckAll;
    const updatedArray = this.state.items.map((item:any) => {
        item.checked = hasToCheckAll;
        return item;
    });

    this.setState({
        ...this.state,
        items: updatedArray,
        hasToCheckAll: hasToCheckAll,
    });
};

handleCheckboxClick = (clickedItem:any) => {
    const updatedArray = this.state.items.map((item:any) => {
        item.checked = item.documentId === clickedItem.documentId ? !item.checked : item.checked;
        return item;
    });

    this.setState({
        ...this.state,
        items: updatedArray,
    });
};

结果:

result-gif

当然,如果有进一步的需要,您可以通过数据操作来扩展此示例。该解决方案是使用 TypeScript 构建的 - 我用它打开了一个项目 - 但您可以删除已添加的类型。

上面的例子很有魅力,我希望这有帮助!

关于javascript - 选择或取消选择复选框 - ReactJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59029061/

相关文章:

javascript - 粘性标题不工作-javascript

javascript - 将 map 转换为数组 - Javascript

javascript - `this` 内部 React 组件生命周期 Hook 的范围问题

reactjs - 抽屉覆盖了material-ui中的AppBar

reactjs - 无法从节点模块自动导入 react 组件

javascript - 在 expo react-native 中将图像转换为 base64(仅在前端): PayloadTooLargeError: request entity too large

Javascript 变量范围混淆

reactjs - webpack:SASS 加载器失败 "Module build failed (from ./node_modules/sass-loader/lib/loader.js)"

reactjs - 如何在material-ui中的自动完成字段中添加清除按钮

reactjs - 如何在 React 中的外部文件上设置 Material UI (withStyle) 样式?