Reactjs 如何防止在React中单击时切换所有accodion组件?
我创建了一个定制的手风琴组件,它同样由两个子组件组成,分别是Reactjs 如何防止在React中单击时切换所有accodion组件?,reactjs,jsx,Reactjs,Jsx,我创建了一个定制的手风琴组件,它同样由两个子组件组成,分别是accordiontle和AccordionContent: AccordionTitle组件有一个按钮。单击时,AccordionContent部件将其样式从显示:无切换到块,再次单击时返回 手风琴标题.js class AccordionTitle extends Component { constructor() { super(); this.show = false; } toggle() {
accordiontle
和AccordionContent
:
AccordionTitle
组件有一个按钮。单击时,AccordionContent
部件将其样式从显示:无
切换到块
,再次单击时返回
手风琴标题.js
class AccordionTitle extends Component {
constructor() {
super();
this.show = false;
}
toggle() {
this.show = !this.show;
if (this.props.onToggled) this.props.onToggled(this.show);
}
render() {
return (
<div style={this.props.style}>
<Button onClick={e => this.toggle(e)} />
{this.props.children}
</div>
);
}
}
export default AccordionTitle;
class AccordionContent extends Component {
render() {
let style = this.props.style ? this.props.style : {};
style = JSON.parse(JSON.stringify(style));
style.display = this.props.show ? 'block' : 'none';
return (
<div style={style}>
{this.props.children}
</div>
);
}
}
export default AccordionContent;
class Accordion extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;
export default Accordion;
import React, { Component } from 'react';
import Accordion from '../Accordion/Accordion';
class ProductAccordion extends Component {
constructor() {
super();
this.state = {
show: false,
};
}
toggled() {
this.setState({
show: !this.state.show,
});
}
render() {
this.productsJsx = [];
const products = this.props.products;
for (let i = 0; i < products.length; i += 1) {
this.productsJsx.push(
<Accordion.Title onToggled={e => this.toggled(e, this)}>
{products[i].name}
<img src="{products[i].imgsrc}" />
</Accordion.Title>,
<Accordion.Content show={this.state.show}>
{products[i].name}<br />
{products[i].grossprice} {products[i].currency}<br />
<hr />
</Accordion.Content>,
);
}
return (
<Accordion style={styles.container}>
{this.productsJsx}
</Accordion>
);
}
}
export default ProductAccordion;
类AccordionTitle扩展组件{
构造函数(){
超级();
this.show=false;
}
切换(){
this.show=!this.show;
如果(this.props.onToggled)this.props.onToggled(this.show);
}
render(){
返回(
this.toggle(e)}/>
{this.props.children}
);
}
}
导出默认的手风琴标题;
accordiocontent.js
class AccordionTitle extends Component {
constructor() {
super();
this.show = false;
}
toggle() {
this.show = !this.show;
if (this.props.onToggled) this.props.onToggled(this.show);
}
render() {
return (
<div style={this.props.style}>
<Button onClick={e => this.toggle(e)} />
{this.props.children}
</div>
);
}
}
export default AccordionTitle;
class AccordionContent extends Component {
render() {
let style = this.props.style ? this.props.style : {};
style = JSON.parse(JSON.stringify(style));
style.display = this.props.show ? 'block' : 'none';
return (
<div style={style}>
{this.props.children}
</div>
);
}
}
export default AccordionContent;
class Accordion extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;
export default Accordion;
import React, { Component } from 'react';
import Accordion from '../Accordion/Accordion';
class ProductAccordion extends Component {
constructor() {
super();
this.state = {
show: false,
};
}
toggled() {
this.setState({
show: !this.state.show,
});
}
render() {
this.productsJsx = [];
const products = this.props.products;
for (let i = 0; i < products.length; i += 1) {
this.productsJsx.push(
<Accordion.Title onToggled={e => this.toggled(e, this)}>
{products[i].name}
<img src="{products[i].imgsrc}" />
</Accordion.Title>,
<Accordion.Content show={this.state.show}>
{products[i].name}<br />
{products[i].grossprice} {products[i].currency}<br />
<hr />
</Accordion.Content>,
);
}
return (
<Accordion style={styles.container}>
{this.productsJsx}
</Accordion>
);
}
}
export default ProductAccordion;
类AccordionContent扩展组件{
render(){
让style=this.props.style?this.props.style:{};
style=JSON.parse(JSON.stringify(style));
style.display=this.props.show?'block':'none';
返回(
{this.props.children}
);
}
}
导出默认的手风琴内容;
此外,我还使用以下父组件:
Accordion.js
class AccordionTitle extends Component {
constructor() {
super();
this.show = false;
}
toggle() {
this.show = !this.show;
if (this.props.onToggled) this.props.onToggled(this.show);
}
render() {
return (
<div style={this.props.style}>
<Button onClick={e => this.toggle(e)} />
{this.props.children}
</div>
);
}
}
export default AccordionTitle;
class AccordionContent extends Component {
render() {
let style = this.props.style ? this.props.style : {};
style = JSON.parse(JSON.stringify(style));
style.display = this.props.show ? 'block' : 'none';
return (
<div style={style}>
{this.props.children}
</div>
);
}
}
export default AccordionContent;
class Accordion extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;
export default Accordion;
import React, { Component } from 'react';
import Accordion from '../Accordion/Accordion';
class ProductAccordion extends Component {
constructor() {
super();
this.state = {
show: false,
};
}
toggled() {
this.setState({
show: !this.state.show,
});
}
render() {
this.productsJsx = [];
const products = this.props.products;
for (let i = 0; i < products.length; i += 1) {
this.productsJsx.push(
<Accordion.Title onToggled={e => this.toggled(e, this)}>
{products[i].name}
<img src="{products[i].imgsrc}" />
</Accordion.Title>,
<Accordion.Content show={this.state.show}>
{products[i].name}<br />
{products[i].grossprice} {products[i].currency}<br />
<hr />
</Accordion.Content>,
);
}
return (
<Accordion style={styles.container}>
{this.productsJsx}
</Accordion>
);
}
}
export default ProductAccordion;
类手风琴扩展组件{
render(){
返回(
{this.props.children}
);
}
}
手风琴标题=手风琴标题;
Accordion.Content=AccordionContent;
导出默认手风琴;
现在,当我使用手风琴组件时,我可能需要一行多个手风琴,如下所示:
ProductAccordion.js
class AccordionTitle extends Component {
constructor() {
super();
this.show = false;
}
toggle() {
this.show = !this.show;
if (this.props.onToggled) this.props.onToggled(this.show);
}
render() {
return (
<div style={this.props.style}>
<Button onClick={e => this.toggle(e)} />
{this.props.children}
</div>
);
}
}
export default AccordionTitle;
class AccordionContent extends Component {
render() {
let style = this.props.style ? this.props.style : {};
style = JSON.parse(JSON.stringify(style));
style.display = this.props.show ? 'block' : 'none';
return (
<div style={style}>
{this.props.children}
</div>
);
}
}
export default AccordionContent;
class Accordion extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;
export default Accordion;
import React, { Component } from 'react';
import Accordion from '../Accordion/Accordion';
class ProductAccordion extends Component {
constructor() {
super();
this.state = {
show: false,
};
}
toggled() {
this.setState({
show: !this.state.show,
});
}
render() {
this.productsJsx = [];
const products = this.props.products;
for (let i = 0; i < products.length; i += 1) {
this.productsJsx.push(
<Accordion.Title onToggled={e => this.toggled(e, this)}>
{products[i].name}
<img src="{products[i].imgsrc}" />
</Accordion.Title>,
<Accordion.Content show={this.state.show}>
{products[i].name}<br />
{products[i].grossprice} {products[i].currency}<br />
<hr />
</Accordion.Content>,
);
}
return (
<Accordion style={styles.container}>
{this.productsJsx}
</Accordion>
);
}
}
export default ProductAccordion;
import React,{Component}来自'React';
从“../Accordion/Accordion”导入手风琴;
类ProductAccordion扩展组件{
构造函数(){
超级();
此.state={
秀:假,,
};
}
切换(){
这是我的国家({
show:!this.state.show,
});
}
render(){
this.productsJsx=[];
const products=this.props.products;
对于(设i=0;i
{products[i].name}
,
{products[i].name}
{products[i].grossprice}{products[i].currency}
,
);
}
返回(
{this.productsJsx}
);
}
}
导出默认产品手风琴;
如您所见,我正在从Accordion.Title
抓取toggled
事件,并通过toggled()
方法将其绑定到Accordion.Content
的道具show
现在,只要只有一个产品,这就可以很好地工作,但是如果有更多的产品,单击按钮将切换所有AccordionContent
实例
如何更改此选项,以便仅切换属于包含单击按钮的标题的内容部分
我还觉得组件
Accordion
应该通过允许Accordion.Title
将切换的事件直接委托给它的同级Accordion.Content
,来解决这个问题(而不是ProductAccordion
)。如何实现这一点?我建议将打开项的索引存储为状态,而不是布尔值。然后在渲染中,show={this.state.show}
类似于show={this.state.show==i}
完整示例:
import React, { Component } from 'react';
import Accordion from '../Accordion/Accordion';
class ProductAccordion extends Component {
constructor() {
super();
this.state = {
show: null,
};
}
toggled(event, ind) {
const index = this.state.index;
this.setState({ show:ind === index ? null : ind });
}
render() {
this.productsJsx = [];
const products = this.props.products;
for (let i = 0; i < products.length; i += 1) {
this.productsJsx.push(
<Accordion.Title onToggled={e => this.toggled(e, i)}>
{products[i].name}
<img src="{products[i].imgsrc}" />
</Accordion.Title>,
<Accordion.Content show={this.state.show === i}>
{products[i].name}<br />
{products[i].grossprice} {products[i].currency}<br />
<hr />
</Accordion.Content>,
);
}
return (
<Accordion style={styles.container}>
{this.productsJsx}
</Accordion>
);
}
}
export default ProductAccordion;
import React,{Component}来自'React';
从“../Accordion/Accordion”导入手风琴;
类ProductAccordion扩展组件{
构造函数(){
超级();
此.state={
show:null,
};
}
切换(事件,索引){
const index=this.state.index;
this.setState({show:ind==index?null:ind});
}
render(){
this.productsJsx=[];
const products=this.props.products;
对于(设i=0;i
{products[i].name}
,
{products[i].name}
{products[i].grossprice}{products[i].currency}
,
);
}
返回(
{this.productsJsx}
);
}
}
导出默认产品手风琴;
还有这个
class AccordionTitle extends Component {
constructor() {
super();
}
render() {
return (
<div style={this.props.style}>
<Button onClick={this.props.onToggled} />
{this.props.children}
</div>
);
}
}
export default AccordionTitle;
类AccordionTitle扩展组件{
构造函数(){
超级();
}
render(){
返回(
{this.props.children}
);
}
}
导出默认的手风琴标题;
是的,成功了,谢谢!我还将以前的状态存储在this.previous=ind
中的toggle()
中,如果两个值相同,我将this.state.show=-1
,否则无法通过再次单击来关闭已打开的元素。@Timo非常好,很高兴我能提供帮助。