反应迭代当前这个

时间:2016-04-18 10:41:07

标签: javascript reactjs react-jsx jsx

我有一个简单的数据结构,列出了一些信息。问题是,当我点击图标时,它会打开两个内容。我没有找到解决方法如何打开当前的div

class HotSpots extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      isOpen: false,
      icon: 'fa-plus'
    }

  }

  handleClick(event) {
    console.log(this.state.isOpen, 'clicked');
    this.setState({
      isOpen: !this.state.isOpen,
      icon: this.state.icon === 'fa-plus' ? 'fa-remove' : 'fa-plus'
    })
  }

  render() {
    //console.log(DATA.module.hotSpots.popups);

    let items = DATA.module
                    .hotSpots
                    .popups.map(n => 
                                <div data-open={n.openByDefault}
                                     data-coordx={n.config.coords[0]}
                                     data-coordy={n.config.coords[1]}
                                     data-enable-mobile-chords={n.config.useMobileCoords>
                                  <a style={{
                                      marginLeft: n.config.coords[0],
                                      marginRight: n.config.coords[1]
                                     }}
                                     onClick={this.handleClick}>
                                      <i className={`fa ${this.state.icon}`}></i>
                                  </a>
                                  <section data-is-open={this.state.isOpen} className="hotspot-detail">
                                    <h2>{n.headline}</h2>
                                    <p>{n.bodyCopy}</p>
                                  </section>
                                </div>
                               );

    return (
     <section className="hotspots">
       {console.log('status' + this.state.isOpen)}
       <div>{items}</div>
      </section>
    )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return <div name={this.props.name}
                data-src-phone-highres={this.props.srcPhoneHighRes}
                data-src-desktop={this.props.srcDesktop}
                data-src-tablet-highres={this.props.srcTabletHighres}
                data-src-phone={this.props.phone}
                data-src-tablet={this.props.srcTablet}
                data-src-desktop-highres={this.props.srcDesktopHighres}>
      <HotSpots />


      </div>
  }
}

React.render( <App name={DATA.moduleName}
                   srcPhoneHighRes={DATA.images.desktop.externalUrl}

                />, app);

http://codepen.io/agriboz/pen/MyGOMG?editors=0010

提前致谢

2 个答案:

答案 0 :(得分:1)

这是因为您将相同的状态(isOpen)与所有内容相关联。 为了表明这一点修改了你的笔:

handleClick(event) {
this.setState({
  parentClass :event.currentTarget.className,
  isOpen: !this.state.isOpen,
  icon: this.state.icon === 'fa-plus' ? 'fa-remove' : 'fa-plus'
   })
  }

 render() {


let items = DATA.module
                .hotSpots
                .popups.map((n,i) => 
                            <div data-open={n.openByDefault}
                                 data-coordx={n.config.coords[0]}
                                 data-coordy={n.config.coords[1]}
                                 data-enable-mobile-chords={n.config.useMobileCoords}>
                              <a style={{
                                  marginLeft: n.config.coords[0],
                                  marginRight: n.config.coords[1]
                                 }}
                                 onClick={this.handleClick} className={'parent'+i}>
                                  <i className={`fa ${this.state.icon}`}></i>
                              </a>
                              <section data-is-open={this.state.isOpen && (this.state.parentClass===("parent"+i)) } className="hotspot-detail">
                                <h2>{n.headline}</h2>
                                <p>{n.bodyCopy}</p>
                              </section>
                            </div>
                           );

return (
 <section className="hotspots">
   {console.log('status' + this.state.isOpen)}
   <div>{items}</div>
  </section>
)

} }

http://codepen.io/Debabrata89/pen/bpMOOM?editors=0010

希望这有帮助

答案 1 :(得分:1)

正如@XtremeCoder所建议的那样。您未使用唯一的key标识符来跟踪您的活动。因此,在您的反应组件中,按下点击处理程序中的键,如下所示onClick={this.handleClick.bind(this, i, n)然后包含一个新状态i,它可以捕获当前点击的element

  this.state = {
      i: 0,
      isOpen: false,
    }

  }

  handleClick(i,n) {
    this.setState({
      i: i,
      isOpen: !this.state.isOpen,
    })

现在,您可以检查状态更改boolean以显示content并更改icon

//for icon
<i className={`fa ${(this.state.isOpen && this.state.i==i ? 'fa-close' : 'fa-plus')}` }></i>

//for content
<section data-is-open={this.state.isOpen && this.state.i==i} className="hotspot-detail">

这是功能齐全的代码

let DATA = { 
  "module": {
    "name": "E-Hot-PDP-X9405C-X9305C-Series-en_US-2015-03-M24-fullflush",
    "masterName": "E-Hot-PDP-X9405C-X9305C-Series-en_GL-2015-03-M24-fullflush",
    "maintenanceStructure": "Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series",
    "_id": "urn:sony:module:editorial_hotspots:590359239320250140028",
    "isLocalized": "false",
    "masterId": "urn:sony:module:editorial_hotspots:1991426988117153303078371",
    "version": "20160122080005",
    "readyForLive": "No",
    "mode": "full",
    "editorialEnabled": "yes",
    "type": "urn:sony:module:editorial_hotspots",
    "createdAt": 1430303942648,
    "updatedAt": 1453816025859,
    "dependents": [
      "urn:sony:media:image_family:1995667013507913303041209"
    ],
    "config": {
      "style": "dark-text-trans-box",
      "background": "true",
      "grouping": "group-middle",
      "type": "full",
      "variation": {
        "background": "white"
      },
      "layout": {
        "name": "full",
        "text": "full",
        "alignment": "center",
        "columns": [
          "12",
          "0"
        ]
      }
    },
    "hotSpots": {
      "popups": [
        {
          "headline": "Full flush surface",
          "alwaysOpen": "no",
          "openByDefault": "no",
          "bodyCopy": "With thin styling and a full flush screen surface, you’ll enjoy an immersive viewing experience.",
          "dropShadow": "no",
          "bullets": [],
          "links": [],
          "config": {
            "size": "large",
            "useMobileCoords": "no",
            "hotSpotsIcon": "yes",
            "dropShadow": "yes",
            "coords": [
              "10%",
              "31%"
            ]
          }
        },
        {
          "headline": "Wedge",
          "alwaysOpen": "no",
          "openByDefault": "no",
          "bodyCopy": "The unique shape has been designed to increase speaker capacity for a rich, full sound.",
          "dropShadow": "no",
          "bullets": [],
          "links": [],
          "config": {
            "size": "large",
            "useMobileCoords": "no",
            "hotSpotsIcon": "yes",
            "dropShadow": "yes",
            "coords": [
              "78.5%",
              "49%"
            ]
          }
        }
      ],
      "image": {
        "type": "urn:sony:media:image_container",
        "imageFamily": {
          "name": "ImgF-PDP-X9405C-X9305C-Series-2015-03-M24-fullflush",
          "masterName": "ImgF-PDP-X9405C-X9305C-Series-2015-03-M24-fullflush",
          "maintenanceStructure": "Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series",
          "_id": "urn:sony:media:image_family:1995667013507913303041209",
          "isLocalized": "false",
          "masterId": "urn:sony:media:image_family:1995667013507913303041209",
          "localizedImageFamily": {
            "name": "Loc-ImgF-PDP-XBR-X9405C-X9305C-Series-2015-03-M24-fullflush-SOLA",
            "masterName": "Loc-ImgF-PDP-XBR-X9405C-X9305C-Series-2015-03-M24-fullflush-SOLA",
            "maintenanceStructure": "Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series",
            "_id": "urn:sony:localized_image_family:4512059944822603303579063",
            "isLocalized": "false",
            "masterId": "urn:sony:localized_image_family:4512059944822603303579063",
            "locale": "all",
            "version": "20150327064448",
            "readyForLive": "No",
            "type": "urn:sony:localized_image_family",
            "createdAt": 1428930904784,
            "updatedAt": 1428930906576,
            "localizedImageFamilies": [
              {
                "imageFamily": {
                  "_id": "urn:sony:media:image_family:4492784185533253304288460",
                  "isLocalized": "false",
                  "locale": "all",
                  "maintenanceStructure": "Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series",
                  "masterId": "urn:sony:media:image_family:4492784185533253304288460",
                  "masterName": "ImgF-PDP-XBR-X9405C-X9305C-Series-2015-03-M24-fullflush-SOLA",
                  "name": "ImgF-PDP-XBR-X9405C-X9305C-Series-2015-03-M24-fullflush-SOLA",
                  "readyForLive": "No",
                  "type": "urn:sony:media:image_family",
                  "version": "20150327061216",
                  "createdAt": 1428930904949,
                  "updatedAt": 1428930906679,
                  "dependents": [],
                  "images": {
                    "desktop": {
                      "internalUrl": "https://prod-imgws.sony.eu/cms/images/Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series/E-Hot-PDP-X94-X93-en_GL-2015-03-M24-fullflush_XBR-desktop.jpg",
                      "md5": "90e6df273a7fe6ba9ef6411a83a995e3",
                      "mimeType": "image/jpg",
                      "status": "published",
                      "uploadAttempts": 1,
                      "uploadLastAttemptAt": 1428412207508,
                      "assetHandle": [
                        "a|23360418"
                      ]
                    }
                  }
                },
                "locales": [
                  "es_AR",
                  "es_BO",
                  "pt_BR",
                  "es_CL",
                  "es_CO",
                  "es_CR",
                  "es_DO",
                  "es_EC",
                  "es_SV",
                  "es_GT",
                  "es_HN",
                  "es_MX",
                  "es_PA",
                  "es_PY",
                  "es_PE",
                  "es_PR",
                  "es_VE",
                  "es_NI"
                ]
              }
            ],
            "dependents": [
              "urn:sony:media:image_family:4492784185533253304288460"
            ]
          },
          "locale": "all",
          "version": "20150327075311",
          "readyForLive": "No",
          "type": "urn:sony:media:image_family",
          "createdAt": 1428930904791,
          "updatedAt": 1453731785919,
          "dependents": [
            "urn:sony:localized_image_family:4512059944822603303579063"
          ],
          "images": {
            "desktop": {
              "internalUrl": "https://prod-imgws.sony.eu/cms/images/Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series/E-Hot-PDP-X94-X93-en_GL-2015-03-M24-fullflush_desktop.jpg",
              "mimeType": "image/jpg",
              "uploadAttempts": 1,
              "uploadLastAttemptAt": 1427203801114,
              "status": "published",
              "md5": "93a8c28123eede1d42d33871e6553daf",
              "assetHandle": [
                "a|23104311"
              ],
              "externalUrl": "//sonyglobal.scene7.com/is/image/gwtprod/93a8c28123eede1d42d33871e6553daf?fmt=jpeg"
            },
            "phone": {
              "internalUrl": "https://prod-imgws.sony.eu/cms/images/Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series/E-Hot-PDP-X94-X93-en_GL-2015-03-M24-fullflush_phone.jpg",
              "mimeType": "image/jpg",
              "uploadAttempts": 1,
              "uploadLastAttemptAt": 1427203801114,
              "status": "published",
              "md5": "40df54c624e5cebfa27fdae4d3207f5d",
              "assetHandle": [
                "a|23104300"
              ],
              "externalUrl": "//sonyglobal.scene7.com/is/image/gwtprod/40df54c624e5cebfa27fdae4d3207f5d?fmt=jpeg"
            },
            "tablet": {
              "internalUrl": "https://prod-imgws.sony.eu/cms/images/Electronics/05_Televisions_and_Home_Cinema/01_Televisions/X9405C-X9305C-Series/E-Hot-PDP-X94-X93-en_GL-2015-03-M24-fullflush_tablet.jpg",
              "mimeType": "image/jpg",
              "uploadAttempts": 1,
              "uploadLastAttemptAt": 1427203801115,
              "status": "published",
              "md5": "5e9ab8ac405f170a5b24f1ccf1f71c1f",
              "assetHandle": [
                "a|23104304"
              ],
              "externalUrl": "//sonyglobal.scene7.com/is/image/gwtprod/5e9ab8ac405f170a5b24f1ccf1f71c1f?fmt=jpeg"
            }
          }
        }
      }
    },
    "locale": "en_US",
    "contentLocale": "en_US"
  },
  "moduleId": "editorial_hotspots_590359239320250140028",
  "moduleName": "editorial_hotspots"
};



class HotSpots extends React.Component {
  constructor(props, context) {
    super(props, context);
    //this.handleClick = this.handleClick.bind(this);
    this.state = {
      i: 0,
      isOpen: false,
    }

  }

  handleClick(i,n) {
    this.setState({
      i: i,
      isOpen: !this.state.isOpen,
    })
  }

  render() {
    //console.log(DATA.module.hotSpots.popups);

    let items = DATA.module
                    .hotSpots
                    .popups.map((n, i) => 
                                <div key={i}
                                     onClick={this.handleClick.bind(this, i, n)} data-open={n.openByDefault}
                                     data-coordx={n.config.coords[0]}
                                     data-coordy={n.config.coords[1]}
                                     data-enable-mobile-chords={n.config.useMobileCoords}>
                                  <a style={{
                                      marginLeft: n.config.coords[0],
                                      marginRight: n.config.coords[1]
                                     }}
                                     >
                                      <i className={`fa ${(this.state.isOpen && this.state.i==i ? 'fa-close' : 'fa-plus')}` }></i>
                                  </a>
                                  <section data-is-open={this.state.isOpen && this.state.i==i} className="hotspot-detail">
                                    <h2>{n.headline}</h2>
                                    <p>{n.bodyCopy}</p>
                                  </section>
                                </div>
                               );

    return (
     <section className="hotspots">
       {console.log('status' + this.state.isOpen)}
       <div>{items}</div>
      </section>
    )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return <div className={`${DATA.module.config.variation.background} ${DATA.module.config.type}`}
                name={this.props.name}
                data-src-desktop={this.props.srcDesktop}               
                data-src-phone={this.props.phone}
                data-src-tablet={this.props.srcTablet}>
      <HotSpots />


      </div>
  }
}

React.render( <App name={DATA.moduleName}
                   srcDesktop={DATA.module.hotSpots.image.imageFamily.images.desktop.externalUrl}
                   srcPhone={DATA.module.hotSpots.image.imageFamily.images.phone.externalUrl}
                   srcTablet={DATA.module.hotSpots.image.imageFamily.images.tablet.externalUrl}



/>, app);

Codepen:

http://codepen.io/anon/pen/WwJPLe?editors=0010

希望它有所帮助!