react输入复选框选择所有组件

IT技术 javascript reactjs
2021-04-12 04:20:36

我正在尝试构建一个正确的react输入复选框选择所有组件。这个想法是有一个组件<InputCheckboxAll><InputCheckbox>我将能够检查<InputCheckboxAll>所有的<InputCheckbox>都将被选中。

我有两个问题。

  • 如果<InputCheckboxAll>被选中,我无法取消选择任何<InputCheckbox>.
  • 如果所有的<InputCheckbox>都被检查,那么<InputCheckboxAll>应该检查。

这是示例。

var InputCheckboxAll = React.createClass({
  handleChange: function (event) {
    this.props.handleChange(event)
  },
  render: function () {
    return (
    <input
           type='checkbox'
           {...this.props}
           onChange={this.handleChange} />
    )
  }
})

var InputCheckbox = React.createClass({
  getInitialState: function () {
    return {
      checked: this.props.checked
    }
  },
  render: function () {
    var checkedValue = this.props.allChecked ? true : this.state.checked
    return (
    <input
           checked={checkedValue}
           type='checkbox'
           {...this.props}/>
    )
  }
})

var Test = React.createClass({
  getInitialState: function () { return {allChecked: false}; },
  handleChange: function (event) {
    var $elm = $(event.target)
    var checked = $elm.prop('checked')
    this.setState({
      allChecked: checked
    })
  },
  render: function () {
    return (
    <div>
      Select All: <InputCheckboxAll handleChange={this.handleChange}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
    </div>
    )
  }
})

React.render(<Test/>, document.body)
4个回答

我认为可以对您的实现进行一些修改,以更React 的形式实现所需的结果

您首先应该摆脱的是InputCheckboxAll复选框类和类的allCheckedpropsInputCheckbox复选框是一个相对愚蠢的元素,它不应该知道诸如Everything is selected.

取而代之的是,复选框应该被实现为一个简单的选中或未选中的项目

var InputCheckbox = React.createClass({
  getDefaultProps: function () {
    return {
      checked: false
    }
  },
  render: function () {
    return (
    <input
           checked={this.props.checked}
           type='checkbox'
           {...this.props}/>
    )
  }
})

您的应用程序的状态(例如All Selected 的概念)应该从主应用程序进行管理,保持较低级别的元素无状态。主应用程序的状态可以简单地表示每个复选框选中状态:

  getInitialState: function () { 
      return {
        // 3 checkboxes, all initialized as unchecked
        checked: [false, false, false]
      }; 
  },

现在,您可以重新创建渲染函数来绘制 3 个复选框,以及您的全选复选框。每个<InputCheckbox>都可以绑定到this.state.checked数组中自己的数据<Inputcheckbox>更改时,我们将索引绑定到更改处理程序,因此我们知道要修改哪个数组元素。

  render: function () {
    // Recalculate if everything is checked each render, instead of storing it
    var isAllChecked = this.state.checked.filter(function(c) {
        return c;
    }).length === this.state.checked.length;

    return (
    <div>
      Select All: <InputCheckbox 
               onChange={this.selectAll} 
               checked={isAllChecked}/><br/>

      <InputCheckbox 
               checked={this.state.checked[0]} 
               onChange={this.handleChange.bind(this, 0)}/><br/>
      <InputCheckbox 
               checked={this.state.checked[1]} 
               onChange={this.handleChange.bind(this, 1)}/><br/>
      <InputCheckbox 
               checked={this.state.checked[2]} 
               onChange={this.handleChange.bind(this, 2)}/><br/>
    </div>
    )
  }

您不需要存储与All Selected相关的任何状态相反,最好在每次渲染期间重新计算是否选择了所有内容。Select All复选框被选中时,我们只需将 的每个元素设置this.state.checked为 true。

这还有一个优点,当您手动选择所有复选框时,全选复选框将自行检查。

这是一个示例实现:https : //jsfiddle.net/rsupvxry/

github.com/calitek/ReactPatterns 的React.13.Common/FormInputs 下有一个用于输入的module化组件
2021-05-26 04:20:36
我不确定确切的区别,我假设是后者。我想要我们在这里拥有的确切功能,我不想要元素相互嵌套。我也想把这里创建的所有功能都放在某个地方,以便于使用。
2021-05-29 04:20:36
这真的很有帮助!非常感谢你把这些放在一起。当您撰写它时,我对此有一个担忧。我想让它checkbox更加module化,这样我就可以在许多不同的项目中使用它。我不想每次都随身携带这些事件处理程序。我可以使用 mixin,但显然它们已经死了,而且那个isAllCheckedvar 妨碍了。还必须为每个榆树定义状态是多余的。您将如何将其进一步移植为即插即用的module化?
2021-06-14 04:20:36
您希望将哪种类型的功能module化?你想要一组复选框,附带一个全选复选框吗?或者您是否想要一个SelectAllCheckbox可以环绕其他基本复选框?这样,您就可以处理该元素中的全选逻辑。
2021-06-16 04:20:36
还是 React 根本不允许这样做?
2021-06-17 04:20:36

我很晚才接触到这个线程。以下解决方案适用于以下结构。

有 3 个组件使此功能干净且可重用。

  1. CheckBox - 可重用组件
  2. CheckBoxList - 可重用组件
  3. CityList - 您可以通过克隆创建州列表或任何列表的结束级别。

使用module堆叠闪电战 - https://stackblitz.com/edit/react-check-box-list

独立代码如下

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>React: Select All or DeSelect All</title>
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
        <script type="text/babel">
            function CheckBox({name, value, tick, onCheck}) {
                return (
                    <label>
                        <input
                            name={name}
                            type="checkbox"
                            value={value}
                            checked={tick || false}
                            onChange={onCheck}
                        />
                        {value}
                    </label>
                );
            }

            function CheckBoxList ({options, isCheckedAll, onCheck}) {
                const checkBoxOptions = (
                    <div className="checkbox-list">
                        {options.map((option, index) => {
                            return (
                                <CheckBox key={index} name={option.name} value={option.value} tick={option.checked} onCheck={(e) => onCheck(option.value, e.target.checked)} />
                            );
                        })}
                    </div>
                );

                return (
                    <div className="checkbox-list">
                        <CheckBox name="select-all" value="ALL" tick={isCheckedAll} onCheck={(e) => onCheck('all', e.target.checked)} />
                        {checkBoxOptions}
                    </div>
                );
            }

            class CityList extends React.Component {
                constructor(props) {
                    super(props);

                    this.state = {
                        isAllSelected: false,
                        checkList: [
                            {
                                name: "city",
                                value: "bangalore",
                                checked: false,
                            },
                            {
                                name: "city",
                                value: "chennai",
                                checked: false,
                            },
                            {
                                name: "city",
                                value: "delhi",
                                checked: false,
                            }
                        ]
                    };
                }

                onCheckBoxChange(checkName, isChecked) {
                    let isAllChecked = (checkName === 'all' && isChecked);
                    let isAllUnChecked = (checkName === 'all' && !isChecked);
                    const checked = isChecked;

                    const checkList = this.state.checkList.map((city, index) => {
                        if(isAllChecked || city.value === checkName) {
                            return Object.assign({}, city, {
                                checked,
                            });
                        } else if (isAllUnChecked) {
                            return Object.assign({}, city, {
                                checked: false,
                            });
                        }

                        return city;
                    });

                    let isAllSelected = (checkList.findIndex((item) => item.checked === false) === -1) || isAllChecked;

                    this.setState({
                        checkList,
                        isAllSelected,
                    });

                }

                render() {
                    return (<CheckBoxList options={this.state.checkList} isCheckedAll={this.state.isAllSelected} onCheck={this.onCheckBoxChange.bind(this)} />);
                }
            }

            ReactDOM.render(
                <CityList />,
                document.getElementById('root')
            );
        </script>
    </head>
    <body>
        <div id="root"></div>
    </body>
</html>

有一个简单的包可以解决这个问题grouped-checkboxes

在您的情况下,渲染函数将如下所示:

render: function () {
  return (
    <CheckboxGroup>
      Select All: <AllCheckerCheckbox /><br/>
      <Checkbox id="option-0" onChange={this.handleChange.bind(this, 0)}/><br/>
      <Checkbox id="option-1" onChange={this.handleChange.bind(this, 1)}/><br/>
      <Checkbox id="option-2" onChange={this.handleChange.bind(this, 2)}/><br/>
    </CheckboxGroup>
  )
}

更多示例参见Codesandbox 示例

请小心在不同网站上链接到您自己的内容,您不想成为垃圾邮件发送者您应该在此处包含大部分内容,并将链接仅用作参考。
2021-05-30 04:20:36

我在下面如何检查所有选项:

JS代码:

 const checkAll = (e) => {

  var value  = false

  if(e.target.checked){
    value = true;
  }
  
  Array.from(document.querySelectorAll("input[name="+name+"]"))
       .forEach((checkbox) => {
        document.getElementById(checkbox.id).checked = value;
       });
 }

HTML 代码(全选):

 <input type="checkbox" name="all" onChange={checkAll} />

HTML 代码(选项):

 <input type="checkbox" name={name} id={name+index} value={obj.id} />

这些选项是使用循环创建的,其中 id 对于此类复选框是唯一的。

对不起,如果我问了一个愚蠢的问题,是为了反应框架吗?对我来说,它看起来不像反应组件。
2021-05-28 04:20:36
@JasonLiu 是的,它是 React,我在 Hook 函数中创建了它,其中 checkAll() 是一个可以在您单击检查所有输入时调用的函数。
2021-06-16 04:20:36