[英]React nested components with checkboxes
我有一個網站,其中包含十幾個組件。
每個父組件包含大約5個其他組件。 每個5個組件都包含一個表單。
父組件具有3個復選框。
1:展開該優惠中的所有組件(全部展開),
2:分配該組件中的所有內容(全部分配),
3:擴展組件(擴展產品)。
每個子組件都有兩個復選框。
1:展開組件(也展開產品),
2:分配組件中的所有內容(也分配所有內容)。
所有這些選項均適用於狀態更改。 它們都正常工作。 問題是,當我單擊“父”復選框時,無法取消選擇子級的單個組件。 因此,我無法取消選中子級組件內的復選框(子級擴展產品或子級全部分配)
封閉組件
在父級上擴展產品
在父級中擴展產品,在子級中擴展產品
在父級中展開全部,觸發在父級中展開產品,並觸發在子級組件中展開產品
這是渲染父組件的第一個文件:
class Offer extends React.Component {
constructor(props){
super(props);
this.state = {
checkedItems: new Map()
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const item = e.target.name;
const isChecked = e.target.checked;
this.setState(prevState => ({
checkedItems: prevState.checkedItems.set(item, isChecked)
}));
}
render(){
const { data, country_offer, country_offer_tab, countries, } = this.props;
return (
<div className="offer-wrapper">
<div className={"offer-header " + data[2] }>
<div>
<div className="custom_checkbox">
<div className="custom_checkbox">
<input
type={"checkbox"}
name={`${data[2]}_expand_all`}
className="expand_all"
checked={this.state.checkedItems.get(`${data[2]}_expand_all`) || false}
onChange={this.handleChange}
id={`${data[2]}_expand_all`}
/>
<label htmlFor={`${data[2]}_expand_all`}>Expand all</label>
</div>
<div className="custom_checkbox">
<input
type={"checkbox"}
name={`${data[2]}_assign_all`}
className="assign_all"
checked={this.state.checkedItems.get(`${data[2]}_assign_all`) || false}
onChange={this.handleChange}
id={`${data[2]}_assign_all`}
/>
<label htmlFor={`${data[2]}_assign_all`}>Assign all products</label>
</div>
<div className="custom_checkbox">
<input
type={"checkbox"}
name={`${data[2]}_expand_product`}
className="expand_product"
checked={( this.state.checkedItems.get(`${data[2]}_expand_product`) || this.state.checkedItems.get(`${data[2]}_expand_all`) ) || false}
onChange={this.handleChange}
id={`${data[2]}_expand_product`}
/>
<label htmlFor={`${data[2]}_expand_product`}>Expand product</label>
</div>
</div>
</div>
</div>
{
(this.state.checkedItems.get(`${data[2]}_expand_all`) || this.state.checkedItems.get(`${data[2]}`+'_expand_product')) &&
<CountryOffer
country_offer_tab={country_offer_tab}
countries={countries}
data={data}
expand_all={this.state.checkedItems.get(`${data[2]}_expand_all`)}
expand_product={this.state.checkedItems.get(`${data[2]}_expand_product`)}
assign_all={this.state.checkedItems.get(`${data[2]}_assign_all`)}
/>
}
</div>
)
}
}
export default Offer;
這是子組件
class CountryOffer extends React.Component{
constructor(props){
super(props);
this.state = {
checkedItems: new Map(),
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
if (!this.props.expand_all){
const item = e.target.name;
const isChecked = e.target.checked;
this.setState(prevState => ({
checkedItems: prevState.checkedItems.set(item, isChecked)
}));
} else {
console.log('cant uncheck/check this')
}
}
render(){
const { country_offer_tab, countries, data, expand_all, expand_product, assign_all} = this.props;
return (
<div className={"offer-details " + data[2]}>
{country_offer_tab[data[2]].map((country, k) => {
return (
<div key={k}>
<div className="offer-country-header" >
<div>
<span className={"iti-flag "+(countries[k].symbol).toLowerCase()}/>
<span>{countries[k].name}</span>
</div>
<div className='custom_checkbox'>
<input
checked={assign_all ? assign_all : (this.state.checkedItems.get(`intersections_for ${data[2]}|${countries[k].id}`) || false)} onChange={this.handleChange}
type="checkbox"
name={"intersections_for "+ data[2] + '|' + countries[k].id}
id={"intersections_for "+ data[2] + '|' + countries[k].id}/>
<label className="intersections_group_label" htmlFor={"intersections_for "+ data[2] + '|' + countries[k].id}>Check/uncheck all</label>
</div>
<div className='custom_checkbox'>
<input
checked={expand_all ? expand_all : (this.state.checkedItems.get(`expand_geo ${data[2]}|${countries[k].id}`) || false)} onChange={this.handleChange}
type="checkbox"
name={"expand_geo " + data[2] + '|' + countries[k].id}
id={"expand_geo " + data[2] + '|' + countries[k].id}/>
<label htmlFor={"expand_geo "+ data[2] + '|' + countries[k].id}>Expand GEO</label>
</div>
</div>
{
(expand_all || this.state.checkedItems.get(`expand_geo ${data[2]}|${countries[k].id}`)) &&
<CountryOfferIntersections
country_offer_tab={country_offer_tab}
offer_id={data[2]}
country_id={countries[k].id}
check_all={this.state.checkedItems.get(`intersections_for ${data[2]}|${countries[k].id}`)}
assign_all={assign_all}
expand_product={expand_product}
/>
}
</div>
)
})}
</div>
)}
}
export default CountryOffer;
我將不勝感激
如果為true
,則assign_all
CountryOffer
會覆蓋CountryOffer
任何本地狀態
checked={assign_all ? assign_all : ...
這是沒有單一真相來源的問題。 我將重構您的代碼,以使CountryOffer
是無狀態組件,並將所有狀態保留在父Offer
組件中。
或者,將共享狀態的管理完全從組件中刪除。 (例如與react context ,redux,rxjs一起使用)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.