2016-11-25 15 views
4

我创建了一个父组件PicturesFetch,它呈现另一个(子)组件,Picture,它呈现一个带有图片的div。现在,要呈现PicturePicturesFetch需要经过一个对象(图片),而.map()函数会创建包含图片的多个div。我希望能够更改单独创建的每个元素的状态。以下是我试过到目前为止,测试结合进行了尝试一个接一个,没有一起:在.map()函数中为每个组件绑定onClick

PictureFetch.js

class PicturesFetch extends React.Component { 
constructor(props) { 
    super(props); 
     this.state = { 
      isSelected: true, 
      pictureClassName: "picture-div green", 
      pics : [/*Object witch contains names and src of the images*/] 
     }; 
    this.handlePictureClick = this.handlePictureClick.bind(this); /*#1 tested bind*/ 
} 
handlePictureClick (isSelected){ 
    if (!isSelected) { 
     this.setState({ 
      isSelected: true, 
      pictureClassName: "picture-div green" 
     }) 
    } else { 
     this.setState({ 
      isSelected: false, 
      pictureClassName: "picture-div none" 
     }) 
    } 
} 
render() { 
    var changeClass = this.state.pictureClassName; 
    var handlePictureClick = this.handlePictureClick.bind(this); /*#2 tested bind*/ 
    var pics = this.state.pics.map(function(pic, i){ 
     if (/*something*/) { 
      return (
      <div className="pic-div" key={i} > 
       <Picture 
        isSelected={isSelected} 
        pictureClassName={changeClass} 
        onClick={handlePictureClick.bind(this, isSelected)} /*#3 tested bind*/ 
       /> 
      </div> 
      }); 
     } 
    return (
    <div className="Options-container"> 
     <div className="container">{pics}</div> 
    </div> 
    ); 
}} 

Picture.js

class Picture extends React.Component { 
constructor(props) { 
    super(props); 
     this.state = { 
      isSelected: true, 
      pictureClassName: "picture-div green" 
     }; 
} 
render() { 
    var pictureClassName = this.props.pictureClassName; 
    return (
     <div onClick={this.props.onClick} className={pictureClassName}> 
      <img src={this.props.src} alt={this.props.name} /> 
      <h5>{this.props.name}</h5> 
     </div> 
    ) 
}} 

我简化了我的例子的代码。现在,通过将绑定置于位置#1和#2更改全部图像状态一起,而在#3给我错误无法读取未定义的属性'setState'

哪个是绑定onClick函数的正确位置,以便我可以分别访问每个图像状态?也许我的结构有缺陷?先谢谢你。

回答

3

您可以使用#1或#3绑定onClick函数。在#3中,您在handlePictureClick中忽略了这一点。

第二部分分别访问每个图像状态。您必须将isSelected和pictureClassName键放入每个pic对象中。 和handlePictureClick可以修改如下。

 handlePictureClick (pic){ 
      this.setState(pics : this.state.pics.map(function(picture){ 
       if(picture.id === pic.id){ 
       if(picture.isSelected){ 
        picture.isSelected = false; 
        picture.pictureClassName = "picture-div none"; 
       } else { 
        picture.isSelected = true; 
        picture.pictureClassName = "picture-div green"; 
       } 

       } 
       return picture; 
     )); 
    } 

    render() { 
    var changeClass = this.state.pictureClassName; 
     var pics = this.state.pics.map(function(pic, i) { 
      if (/*something*/) { 
       return (
       <div className="pic-div" key={i} > 
        <Picture 
         isSelected={pic.isSelected} 
         pictureClassName={changeClass} 
         onClick={this.handlePictureClick.bind(this, pic)} 
        /> 
       </div> 
       } 
      }); 
     return (
     <div className="Options-container"> 
      <div className="container">{pics}</div> 
     </div> 
     ); 
} 
+0

在'handlePictureClick'对'下联:'它说,','预期,在第二最后'''说声明或声明预期 –

+0

应该是:this.setState({pics:this.state.pics.map(function(picture){....})}); 注意:开始和结束花括号{} – Zinc

+0

@锌是的,这改正了电话,谢谢。 –

2

添加到由@dulwalanise问题给出的溶液可以通过绑定解决的地图功能的上下文。 this.handlePictureClick是不确定的,因为这里this并未提及,而功能部件的语境映射的内部

使用本

handlePictureClick (pic){ 
     this.setState(pics : this.state.pics.map(function(picture){ 
      if(picture.id === pic.id){ 
      if(picture.isSelected){ 
       picture.isSelected = false; 
       picture.pictureClassName = "picture-div none"; 
      } else { 
       picture.isSelected = true; 
       picture.pictureClassName = "picture-div green"; 
      } 

      } 
      return picture; 
    )); 
} 

render() { 
var changeClass = this.state.pictureClassName; 
    var pics = this.state.pics.map(function(pic, i) { 
     if (/*something*/) { 
      return (
      <div className="pic-div" key={i} > 
       <Picture 
        isSelected={pic.isSelected} 
        pictureClassName={changeClass} 
        onClick={this.handlePictureClick.bind(this, pic)} 
       /> 
      </div> 
      } 
     }.bind(this)); 
    return (
    <div className="Options-container"> 
     <div className="container">{pics}</div> 
    </div> 
    ); 
} 
1

我想你,你应该使用第一个绑定选项。

您的isSelected布尔值由您所有的子图片共享,所以当iselected为true时,它适用于所有图片组件。

我做了一个工作小提琴here

class PicturesFetch extends React.Component { 
constructor(props) { 
super(props); 
    this.state = { 
     selected: null, 
     pictureClassName: "picture-div green", 
     pics : [{name : '1'},{name : '2'},{name : '3'},{name : '4'}] 
    }; 
this.handlePictureClick = this.handlePictureClick.bind(this); /*#1  tested bind*/ 
} 
handlePictureClick (itemSelected){  
console.log(itemSelected) 
    this.setState({ 
     selected: itemSelected, 
     pictureClassName: "picture-div green" 
    }) 
} 
render() { 
    var changeClass = this.state.pictureClassName; 
    var selected = this.state.selected; 
    var click = this.handlePictureClick; 
    var pics = this.state.pics.map((pic, i) => {  
    var itemSelected = selected && selected.name ===  pic.name; 
     return (
     <div className="pic-div" key={i} > 
      <Picture 
       isSelected={itemSelected} 
       pictureClassName={changeClass} 
       onClick={click} 
       pic={pic} 
      /> 
     </div> 
     ); 
    }); 
return (
    <div className="Options-container"> 
     <div className="container">{pics}</div> 
    </div> 
) 
}} 
class Picture extends React.Component { 
    constructor(props) { 
    super(props);  
    } 
    render() { 
    var pictureClassName = this.props.pictureClassName; 
    console.log(this.props.isSelected) 
    return (
    <div onClick={() => this.props.onClick(this.props.pic)}  className={pictureClassName}> 
     <h5>{this.props.pic.name} {this.props.isSelected ? 'selected' : 'not selected'}</h5> 
     </div> 
    ) 
}} 

我希望它帮你

+0

解决了。是的,这是一个很好的解决方法。虽然我想要多个选择,但是这个代码可以很容易地修改来做到这一点。如果您不介意的话,我还会对代码进行格式化以使其更加清晰。谢谢! –

相关问题