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非常好,很高兴我能提供帮助。