我创建了一个父组件PicturesFetch
,它呈现另一个(子)组件Picture
,它会在里面呈现带有图片的div。现在,为了渲染Picture
,PicturesFetch
遍历一个对象(图片),并使用.map()函数创建多个带有图像的div。我希望能够更改单独创建的每个元素的状态。这是我到目前为止所尝试的,测试的绑定是一个接一个地尝试,而不是一起尝试:
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函数的正确位置,所以我可以分别访问每个图像状态?也许我的结构存在缺陷?提前谢谢。
答案 0 :(得分:4)
您可以使用#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>
);
}
答案 1 :(得分:3)
添加@dulwalanise给出的解决方案可以通过将map函数绑定到上下文来解决问题。 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>
);
}
答案 2 :(得分:3)
我认为您应该使用第一个绑定选项。
您的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>
)
}}
我希望它对你有所帮助