Reactjs 在react中实现复选框

Reactjs 在react中实现复选框,reactjs,react-redux,redux-saga,Reactjs,React Redux,Redux Saga,我正在尝试实现产品列表表 我所做的是 import React, { Component } from 'react'; import { Row, Col, Card, CardBody } from 'reactstrap'; import { withRouter, Link } from 'react-router-dom'; import { activateAuthLayout, onLoad } from '../../../store/action

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

我所做的是

    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));
为什么我不能在构造函数中获取此.props.product,而只能在渲染中获取?
谢谢

您保留一个已检查项目数组的想法非常接近,尽管我建议您使用地图,这样您就可以对已检查项目状态进行
O(1)
定时查找

主旨 保留选中项目id的映射,
onChange
传递输入id和选中值,该id用于检索选中值

管理选中状态的更改 更新
handleIndividualCheck
以分解
checked
并从事件中输入
id
,并更新checked状态

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}
        />
        ...
      );
    }
}
更新
TableRow
input以使用产品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}
      />
    )
  );
}
<input
  type="checkbox"
  id={propduct.id} // <-- Pass product id to input id for event
  checked={this.props.is_checked}
  onChange={this.props.handleIndividualCheck}
/>

向你致敬,先生。多谢各位。
<input
  type="checkbox"
  id={propduct.id} // <-- Pass product id to input id for event
  checked={this.props.is_checked}
  onChange={this.props.handleIndividualCheck}
/>
handleIndividualCheck = event => {
  const { checked, id } = event.target;
  this.setState(prevState => ({
    checked: {
      ...prevState.checked,
      [id]: checked
    },
  }));

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