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
}
}