在反应中实现复选框 [英] Implementing check boxes in react

查看:35
本文介绍了在反应中实现复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现产品列表.

我所做的如下,

 import React, { Component } from 'react';从reactstrap"导入 { Row, Col, Card, CardBody };从'react-router-dom'导入{ withRouter,链接};import { activateAuthLayout, onLoad } from '../../../store/actions';从'react-redux'导入{连接};从'../Subpages/Settingmenu'导入设置菜单;//图片从'../../../images/users/user-1.jpg'导入default_image;const ListProducts = props =>{if (props.is_loading === true)返回 (<tr><td colSpan=7">正在加载....</td></tr>);返回 (props.products.map(product => {返回  a.inventory_quantity),total_count = 数量.reduce((a, b) => a + b, 0) + ' in stock ';返回 (<tr><td><输入类型=复选框"已检查={this.props.is_checked}onChange={this.props.handleIndividualCheck}/></td><td><div className=media mb-4"><img className="d-flex align-self-start rounded mr-3";src={this.props.product.image ?this.props.product.image.src : default_image} alt=Veltrix"高度=64"/><div className="media-body"><p style={{ fontWeight: '600', fontSize: 'small' }} className=product-list-title text-justify">{this.props.product.title}</p>

</div></td><td style={{ textAlign: "center"}}>{total_count}</td><td><span className=徽章徽章-软-主要徽章-药丸"><i className=mdi mdi-checkbox-blank-circle mr-1"</i>{this.props.product.product_type ||'n/a'}</span></td><td>{this.props.product.vendor}</td></tr>)}}类 ProductLists 扩展组件 {构造函数(道具){超级(道具);this.state = {};}使成为() {控制台日志(this.props)返回 (<table className="table project-table"><头><tr><th style={{ width: '3px' }}><input onClick={this.props.handleSelectCheckbox} type=checkbox"/></th><th style={{ width: '30%' }} scope=col">Products</th><th style={{ textAlign: 'center' }} scope=col">Inventory</th><th style={{ width: '15p%' }} scope=col">type</th><th scope=col">Vendor</th></tr></thead><列出产品产品={this.props.products}is_loading={this.props.is_loading}is_checked={this.props.is_checked}handleIndividualCheck={this.props.handleIndividualCheck}/></tbody>);}}类 EcommerceProductEdit 扩展组件 {构造函数(道具){超级(道具);this.state = { 已检查:false }}componentDidMount() {this.props.activateAuthLayout();if (this.props.user !== null && this.props.user.shop_id)this.props.onLoad({有效载荷:this.props.user});}handleSelectCheckbox = 事件 =>{this.setState({ 检查: !this.state.checked });};handleIndividualCheck = 事件 =>{控制台日志(事件);}使成为() {返回 (<React.Fragment><div className="内容"><div className="container-fluid"><div className="page-title-box"><Row className="align-items-center"><Col sm=6"><h4 className="page-title">产品 </h4><ol className=面包屑"><li className=breadcrumb-item"><Link to=#"><i className=mdi mdi-home-outline"></i></Link></li><li className="breadcrumb-item active">Products</li></ol></Col><Col sm=6"><div className="float-right d-none d-md-block"><设置菜单/>

</Col></行>

<行><Col xl=3"md=6"><Card className="bg-pattern"><卡片体><div className="float-right"><i className="dripicons-archive text-primary h4 ml-3"</i>

<h5 className="font-20 mt-0 pt-1">24</h5><p className="text-muted mb-0">总项目</p></CardBody></卡片></Col><Col xl=3"md=6"><Card className="bg-pattern"><卡片体><div className="float-right"><i className="dripicons-trophy text-primary h4 ml-3"</i>

<h5 className="font-20 mt-0 pt-1">18</h5><p className="text-muted mb-0">已完成的项目</p></CardBody></卡片></Col><Col xl=3"md=6"><Card className="bg-pattern"><卡片体><div className="float-right"><i className="dripicons-hourglass text-primary h4 ml-3"</i>

<h5 className="font-20 mt-0 pt-1">06</h5><p className="text-muted mb-0">待定项目</p></CardBody></卡片></Col><Col xl=3"md=6"><卡片><卡片体><表格><div className="form-group mb-0"><label>搜索</label><div className="input-group mb-0"><输入类型=文本"className =表单控件"placeholder="搜索...";aria-描述的=项目搜索插件";/><div className="input-group-append"><button className="btn btn-danger";类型=按钮"id="project-search-addon">

</表单></CardBody></卡片></Col></行><行><Col lg=12"><卡片><卡片体><div className="table-responsive project-list"><产品列表{...this.props}handleIndividualCheck={this.handleIndividualCheck}is_checked={this.state.checked}handleSelectCheckbox={this.handleSelectCheckbox}/>

<div className="pt-3"><ul className="pagination justify-content-end mb-0"><li className="页面项已禁用"><Link className="页面链接";到=#"tabIndex="-1";aria-disabled="true">Previous</Link><li className="page-item"><Link className="page-link"to=#">1</Link></li><li className="page-item active"><Link className="page-link"to=#">2</Link></li><li className="page-item"><Link className="page-link"to=#">3</Link></li><li className="page-item"><Link className="页面链接";to=#">下一个

</CardBody></卡片></Col></行>

</React.Fragment>);}}const mapStatetoProps = state =>{const { 用户,is_logged_in } = state.Common;const { products, is_loading } = state.Products;返回 { 用户, is_logged_in, 产品, is_loading };}导出默认 withRouter(connect(mapStatetoProps, { activateAuthLayout, onLoad })(EcommerceProductEdit));

我现在需要在用户检查未选中某些列表时执行操作.我怎么做 ?它是否在选中/取消选中后生成选中/未选中项目的数组,或者还有其他方法可以使用 this.props.products 对象列表吗?

非常感谢任何建议.

也在 EcommerceProductEdit 组件中执行后确实挂载

 this.props.onLoad({有效载荷:this.props.user});

为什么我无法在构造函数中获得 this.props.product 而只能在 render 中获得?谢谢

解决方案

您保留一组已检查项目的想法很接近,但我建议使用地图以便您拥有 O(1) 对检查项目状态的持续时间查找.

要点

保留一个checked item id的映射,onChange传递输入的id和checked值,id用来获取checked值.

管理检查状态的变化

更新handleIndividualCheck 以解构checked 并从事件中输入id 并更新checked 状态.

class EcommerceProductEdit 扩展组件 {构造函数(道具){超级(道具);this.state = {已检查:{},//<-- 将 id 存储为键并将检查状态存储为值的对象};}...handleIndividualCheck = 事件 =>{const { 检查,id } = event.target;this.setState(prevState => ({检查:{...prevState.checked,[id]:选中},}));}使成为() {返回 (...<产品列表{...this.props}handleIndividualCheck={this.handleIndividualCheck}is_checked={this.state.checked}handleSelectCheckbox={this.handleSelectCheckbox}/>...);}}

更新 ListProducts 以通过产品 ID 检查 is_checked 属性

const ListProducts = props =>{...返回 (props.products.map(product => {返回 

更新 TableRow 输入以使用产品 ID 命名输入

<输入类型=复选框"id={propduct.id}//<-- 将产品 id 传递给事件的输入 id已检查={this.props.is_checked}onChange={this.props.handleIndividualCheck}/>

更改为处理对未选中项执行操作

<块引用>

我现在需要在用户检查未选中某些列表时执行操作.我该怎么做?

您可以在处理程序中检查输入是否未选中并执行操作.

handleIndividualCheck = event =>{const { 检查,id } = event.target;this.setState(prevState => ({检查:{...prevState.checked,[id]:选中},}));如果(!检查){//根据 id 对产品进行操作}}

I am trying to implement product list table.

What i have done is as under,

    import React, { Component } from 'react';
    import { Row, Col, Card, CardBody } from 'reactstrap';
    import { withRouter, Link } from 'react-router-dom';
    import { activateAuthLayout, onLoad } from '../../../store/actions';
    import { connect } from 'react-redux';
    import Settingmenu from '../Subpages/Settingmenu';
    //images
    import default_image from '../../../images/users/user-1.jpg';

    const ListProducts = props => {
        if (props.is_loading === true)
            return (
                <tr>
                    <td colSpan="7">Loading....</td>
                </tr>
            );

        return (
            props.products.map(product => {
                return <TableRow
                    key={product.id}
                    product={product}
                    is_checked={props.is_checked}
                    handleIndividualCheck={props.handleIndividualCheck}
                />
            })
        );

    }

    class TableRow extends Component {

        constructor(props) {
            super(props);
            this.state = {}
        }

        render() {
            console.log(this.props);
            let quantities = this.props.product.variants.map(a => a.inventory_quantity),
                total_count = quantities.reduce((a, b) => a + b, 0) + ' in stock ';
            return (
                <tr>
                    <td>
                        <input
                            type="checkbox"
                            checked={this.props.is_checked}
                            onChange={this.props.handleIndividualCheck}
                        />
                    </td>
                    <td><div className="media mb-4">
                        <img className="d-flex align-self-start rounded mr-3" src={this.props.product.image ? this.props.product.image.src : default_image} alt="Veltrix" height="64" />
                        <div className="media-body">
                            <p style={{ fontWeight: '600', fontSize: 'small' }} className="product-list-title text-justify">{this.props.product.title}</p>
                        </div>
                    </div></td>
                    <td style={{ textAlign: "center" }}>{total_count}</td>
                    <td><span className="badge badge-soft-primary badge-pill"><i className="mdi mdi-checkbox-blank-circle mr-1"></i>{this.props.product.product_type || 'n/a'}</span></td>

                    <td>
                        {this.props.product.vendor}
                    </td>
                </tr>
            )
        }
    }

    class ProductLists extends Component {
        constructor(props) {
            super(props);
            this.state = {};
        }

        render() {
            console.log(this.props)
            return (
                <table className="table project-table">
                    <thead>
                        <tr>
                            <th style={{ width: '3px' }}><input onClick={this.props.handleSelectCheckbox} type="checkbox" /></th>
                            <th style={{ width: '30%' }} scope="col">Products</th>
                            <th style={{ textAlign: 'center' }} scope="col">Inventory</th>
                            <th style={{ width: '15p%' }} scope="col">type</th>
                            <th scope="col">Vendor</th>
                        </tr>
                    </thead>
                    <tbody>

                        <ListProducts
                            products={this.props.products}
                            is_loading={this.props.is_loading}
                            is_checked={this.props.is_checked}
                            handleIndividualCheck={this.props.handleIndividualCheck}
                        />

                    </tbody>
                </table>
            );
        }
    }

    class EcommerceProductEdit extends Component {

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

        componentDidMount() {
            this.props.activateAuthLayout();
            if (this.props.user !== null && this.props.user.shop_id)
                this.props.onLoad({
                    payload: this.props.user
                });
        }

        handleSelectCheckbox = event => {
            this.setState({ checked: !this.state.checked });
        };

        handleIndividualCheck = event => {
            console.log(event);
        }

        render() {

            return (
                <React.Fragment>
                    <div className="content">
                        <div className="container-fluid">
                            <div className="page-title-box">
                                <Row className="align-items-center">
                                    <Col sm="6">
                                        <h4 className="page-title">Products </h4>
                                        <ol className="breadcrumb">
                                            <li className="breadcrumb-item"><Link to="#"><i className="mdi mdi-home-outline"></i></Link></li>
                                            <li className="breadcrumb-item active">Products</li>
                                        </ol>
                                    </Col>
                                    <Col sm="6">
                                        <div className="float-right d-none d-md-block">
                                            <Settingmenu />
                                        </div>
                                    </Col>
                                </Row>
                            </div>

                            <Row>
                                <Col xl="3" md="6">
                                    <Card className="bg-pattern">
                                        <CardBody>
                                            <div className="float-right">
                                                <i className="dripicons-archive text-primary h4 ml-3"></i>
                                            </div>
                                            <h5 className="font-20 mt-0 pt-1">24</h5>
                                            <p className="text-muted mb-0">Total Projects</p>
                                        </CardBody>
                                    </Card>
                                </Col>
                                <Col xl="3" md="6">
                                    <Card className="bg-pattern">
                                        <CardBody>
                                            <div className="float-right">
                                                <i className="dripicons-trophy text-primary h4 ml-3"></i>
                                            </div>
                                            <h5 className="font-20 mt-0 pt-1">18</h5>
                                            <p className="text-muted mb-0">Completed Projects</p>
                                        </CardBody>
                                    </Card>
                                </Col>
                                <Col xl="3" md="6">
                                    <Card className="bg-pattern">
                                        <CardBody>
                                            <div className="float-right">
                                                <i className="dripicons-hourglass text-primary h4 ml-3"></i>
                                            </div>
                                            <h5 className="font-20 mt-0 pt-1">06</h5>
                                            <p className="text-muted mb-0">Pending Projects</p>
                                        </CardBody>
                                    </Card>
                                </Col>
                                <Col xl="3" md="6">
                                    <Card>
                                        <CardBody>
                                            <form>
                                                <div className="form-group mb-0">
                                                    <label>Search</label>
                                                    <div className="input-group mb-0">
                                                        <input type="text" className="form-control" placeholder="Search..." aria-describedby="project-search-addon" />
                                                        <div className="input-group-append">
                                                            <button className="btn btn-danger" type="button" id="project-search-addon"><i className="mdi mdi-magnify search-icon font-12"></i></button>
                                                        </div>
                                                    </div>
                                                </div>
                                            </form>
                                        </CardBody>
                                    </Card>
                                </Col>
                            </Row>

                            <Row>
                                <Col lg="12">
                                    <Card>
                                        <CardBody>
                                            <div className="table-responsive project-list">
                                                <ProductLists
                                                    {...this.props}
                                                    handleIndividualCheck={this.handleIndividualCheck}
                                                    is_checked={this.state.checked}
                                                    handleSelectCheckbox={this.handleSelectCheckbox}
                                                />
                                            </div>


                                            <div className="pt-3">
                                                <ul className="pagination justify-content-end mb-0">
                                                    <li className="page-item disabled">
                                                        <Link className="page-link" to="#" tabIndex="-1" aria-disabled="true">Previous</Link>
                                                    </li>
                                                    <li className="page-item"><Link className="page-link" to="#">1</Link></li>
                                                    <li className="page-item active"><Link className="page-link" to="#">2</Link></li>
                                                    <li className="page-item"><Link className="page-link" to="#">3</Link></li>
                                                    <li className="page-item">
                                                        <Link className="page-link" to="#">Next</Link>
                                                    </li>
                                                </ul>
                                            </div>


                                        </CardBody>
                                    </Card>
                                </Col>
                            </Row>

                        </div>
                    </div>
                </React.Fragment>

            );
        }
    }

    const mapStatetoProps = state => {
        const { user, is_logged_in } = state.Common;
        const { products, is_loading } = state.Products;
        return { user, is_logged_in, products, is_loading };
    }

    export default withRouter(connect(mapStatetoProps, { activateAuthLayout, onLoad })(EcommerceProductEdit));

I need to now when user check unchecked some of the lists to perform operation. How do I do that ? Do it make the array of checked / unchecked items after the are checked/unchecked, or is there other way that i can do with this.props.products object lists ?

Any kin d of suggestion are highly appreciated.

Also In EcommerceProductEdit component did mount after performing

  this.props.onLoad({
                payload: this.props.user
            });

why i am not being able to get this.props.product in constructor but only in render ? Thanks

解决方案

Your idea to keep an array of checked items is close, though I'd suggest using a map so you have O(1) constant time lookups of checked item status.

Gist

Keep a map of checked item id's, the onChange passes the input id and checked value, and the id is used to retrieve the checked value.

Changes to Manage Checked State

Update handleIndividualCheck to destructure checked and input id from the event and update the checked state.

class EcommerceProductEdit extends Component {

    constructor(props) {
      super(props);
      this.state = {
        checked: {}, // <-- Object to store id's as keys and checked status as values
      };
    }

    ...

    handleIndividualCheck = event => {
      const { checked, id } = event.target;
      this.setState(prevState => ({
        checked: {
          ...prevState.checked,
          [id]: checked
        },
      }));
    }

    render() {
      return (
        ...
        <ProductLists
          {...this.props}
          handleIndividualCheck={this.handleIndividualCheck}
          is_checked={this.state.checked}
          handleSelectCheckbox={this.handleSelectCheckbox}
        />
        ...
      );
    }
}

Update ListProducts to check the is_checked prop by product id

const ListProducts = props => {
  ...

  return (
    props.products.map(product => {
      return <TableRow
        key={product.id}
        product={product}
        is_checked={props.is_checked[product.id]} // <-- is_checked now checked value from checked map!
        handleIndividualCheck={props.handleIndividualCheck}
      />
    )
  );
}

Update TableRow input to name the input with the product id

<input
  type="checkbox"
  id={propduct.id} // <-- Pass product id to input id for event
  checked={this.props.is_checked}
  onChange={this.props.handleIndividualCheck}
/>

Change to Handle Performing Operation on Unchecked Item

I need to now when user check unchecked some of the lists to perform operation. How do I do that?

You can check if an input was unchecked right in the handler and perform operation.

handleIndividualCheck = event => {
  const { checked, id } = event.target;
  this.setState(prevState => ({
    checked: {
      ...prevState.checked,
      [id]: checked
    },
  }));

  if (!checked) {
    // perform operation on product by id
  }
}

这篇关于在反应中实现复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆