在反应中实现复选框 [英] Implementing check boxes in react
问题描述
我正在尝试实现产品列表.
我所做的如下,
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屋!