React - 使用“全选”复选框选中全部复选框后,无法单独选中复选框

时间:2017-10-16 16:34:50

标签: reactjs

我是React的初学者,我真的很难发现我做错了什么,我正在尝试使用复选复选框的值来填充我的数组positionChecked,以便能够发布有效负载。

我的“位置”复选框在我的DOM旁边的“全选”复选框旁边动态添加。

当我点击我的一个位置复选框时,我可以在控制台上看到该复选框的值已添加到positionChecked [] 但是小蓝色复选框永远不会被触发。触发/取消触发它的唯一方法是单击“全选”复选框。

位置复选框失去了对其状态的控制。

App.js

const items = [
    'Position 1',
    'Position 2',
    'Position 3'
];

class AppG extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            positionChecked: [],
            selectAll: false,
        };
        this.handleCheckboxSelection = this.handleCheckboxSelection.bind(this);
        this.handleSelectAll = this.handleSelectAll.bind(this);
    };

    handleCheckboxSelection(e) {
        e.preventDefault();
        const newSelection = e.target.value;
        let newSelectionArray;
        if(this.state.positionChecked.indexOf(newSelection) > -1) {
            newSelectionArray = this.state.positionChecked.filter(s => s !== newSelection)
        } else {
            newSelectionArray = [...this.state.positionChecked, newSelection];
        }
        this.setState({ positionChecked: newSelectionArray}, () => console.log('position selection', this.state.positionChecked));
    };

    handleSelectAll(e) {
        this.setState({selectAll:e.target.checked}, () => console.log(this.state.selectAll));
    };

    handleSubmit = (e) => {
        e.preventDefault();
        const formPayload = {
            positionChecked: this.state.positionChecked,
        };
        console.log('Send this in a POST request:', formPayload);
        console.log(this.refs.checkbox.value);
    };

    createCheckboxes = (items) => (
        items.map(this.createCheckbox)
    );

    createCheckbox = item => (
        <Checkbox
            inline
            value={item}
            onChange={this.handleCheckboxSelection}
            checked={this.state.selectAll}
            key={'position'}
            type={'checkbox'}>
            {item}
        </Checkbox>
    );

    render() {
        return (
            <div>
                <h1>Reporting by group</h1>
                <Jumbotron>
                    <Grid>
                        <Row className="show-grid">
                            <Col sm={3}>
                            </Col>
                            <Col sm={6}>
                                <form onSubmit={this.handleSubmit} ref={form => this.form = form}>
                                    <InputGroup />
                                    <FormGroup style={styles}>
                                        <Checkbox
                                            inline
                                            onChange={this.handleSelectAll}
                                            checked={this.state.selectAll}
                                            key={'All'}
                                            value={'All'}
                                            type={'checkbox'}>All
                                        </Checkbox>
                                        {this.createCheckboxes(items)}
                                    </FormGroup>
                                    <Datepicker />
                                    <ButtonComponent type="submit" value="Submit"/>
                                </form>
                            </Col>
                            <Col sm={3}>
                                <NavComponent/>
                            </Col>
                        </Row>
                    </Grid>
                </Jumbotron>
            </div>
        );
    }
}

1 个答案:

答案 0 :(得分:0)

试试这个:

createCheckbox = item => (
  <Checkbox
    inline
    value={item}
    onChange={this.handleCheckboxSelection}
    checked={this.state.selectAll || this.state.positionChecked.some(i => i === item)}
    key={'position'}
    type={'checkbox'}>
    {item}
  </Checkbox>
);

这将使checked属性为true或false,具体取决于该项是否存在于positionChecked数组中。

编辑:此外,为了使其正常工作,您必须取消选中“全选”复选框(或者更好的是,如果手动取消选中任何单独的复选框,则强制取消选中)。

Edit2:您还应该考虑更改处理“全选”复选框的方式。它应该添加/删除positionChecked数组中的所有项目,而不是设置单独的布尔值。

Edit3:处理'全部'以不同方式

如果你分解两种复选框类型的用例('全选'与个别选择),我会说你想要达到以下行为:

  • 选中“全选”选中所有单独的复选框
  • 取消选中“全选”取消选中所有单独的复选框
  • 检查单个方框只会检查该方框并保留其他方框
  • 取消选中一个单独的框,取消选中“全选”(如果已选中)

这就是我如何定义两个处理程序来实现这一点,使用你最初定义的状态:

handleCheckboxSelection(e) {
  const item = e.target.value;
  const positionChecked = this.state.positionChecked.some(i => i === item) ? this.state.positionChecked.filter(i => i === item) : [ ...this.state.positionChecked, item ]; 
  this.setState({ selectAll: false, positionChecked }, () => console.log(this.state));
};

handleSelectAll(e) {
  const selectAll = e.target.checked;
  const positionChecked = selectAll ? items : [];
  this.setState({ selectAll, positionChecked }, () => console.log(this.state));
};

单个复选框处理程序获取正在选中/取消选中的项目。如果该项目存在于this.state.positionChecked数组中,则会返回一个新数组,其中该项目将被过滤掉,如果该项目不存在,则返回一个新数组,其中该项目将添加到现有数组中。然后使用这个新数组设置状态,selectAll设置为false(如果this.state.selectAll已经false,我们希望保持这种状态,如果是true我们想要设置false,请参阅上面的用例;将其设置为false涵盖两种情况。)

'select all'处理程序非常简单。我们设置selectAll以反映复选框的已检查状态,如果选中它,我们会将positionChecked数组设置为包含所有项,如果未选中,我们将该数组设置为完全为空(再次参见上面的用例)。

最后,完成后,您可以将checked方法中的createCheckbox值简化为以下内容:

checked={this.state.positionChecked.some(i => i === item)}