我是新手反应的,请原谅我。我的理解状态,尤其是儿童的问题。
perive :我正在尝试创建一个用户可以越来越多的组件的表单 - 在这种情况下,图像。
发生了什么:用户附加了2个或更多图像。用户尝试使用UploadButton
组件上传图像,但是两个图像都是相同的。我相信这与两个附属的儿童共享相同的状态有关。
问题:如何在不影响其他附录的孩子的情况下给每个附录的孩子自己的图像?
class Page extends Component
constructor (props) {
super(props);
this.state = {
id: '',
numChildren: 0,
images: [],
}
this.onAddChild = this.onAddChild.bind(this);
}
showModal() {
this.setState({
numChildren: 0,
images: [],
});
}
renderModal()
const children = [];
//Here's my array of child components
for(var i = 0; i < this.state.numChildren; i += 1) {
children.push(<this.ChildComponent key={i} />);
}
return (
<ReactModal>
<this.ParentComponent addChild={this.onAddChild}>
{children}
</this.ParentComponent>
</ReactModal>
)
}
onAddChild = () => {
this.setState({
numChildren: this.state.numChildren + 1
})
}
ParentComponent = (props) => (
<div>
{props.children}
<Button onClick={props.addChild}>Add Item</Button>
</div>
);
ChildComponent = () => (
<div>
<UploadButton
storage="menus"
value={this.state.images}
onUploadComplete={uri => this.setState({images: uri})}
/>
</div>
);
}
这是UploadButton
的代码:
import React, { Component } from 'react';
import uuid from 'uuid';
import firebase from '../config/firebase';
class UploadButton extends Component {
constructor(props) {
super(props);
this.state = {
isUploading: false
}
}
handleClick() {
const input = document.createElement("INPUT");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/gif, image/jpeg, image/png");
input.addEventListener("change", ({target: {files: [file]}}) => this.uploadFile(file));
input.click();
}
uploadFile(file) {
console.log('F', file);
const id = uuid.v4();
this.setState({ isUploading: true })
const metadata = {
contentType: file.type
};
firebase.storage()
.ref('friends')
.child(id)
.put(file, metadata)
.then(({ downloadURL }) => {
this.setState({ isUploading: false })
console.log('Uploaded', downloadURL);
this.props.onUploadComplete(downloadURL);
})
.catch(e => this.setState({ isUploading: false }));
}
render() {
const {
props: {
value,
style = {},
className = "image-upload-button",
},
state: {
isUploading
}
} = this;
return (
<div
onClick={() => this.handleClick()}
className={className}
style={{
...style,
backgroundImage: `url("${this.props.value}")`,
}}>
{isUploading ? "UPLOADING..." : !value ? 'No image' : ''}
</div>
);
}
}
export default UploadButton;
我试图排除所有不必要的代码与我的问题有关,但是请让我知道我是否需要显示更多。
编辑:这是我的尝试,它行不通:
//altered my children array to include a new prop
renderModal() {
const children = [];
for (var i = 0; i < this.state.numChildren; i += 1) {
children.push(<this.ChildComponent imageSelect={this.onImageSelect} key={i} />);
}
//...
};
//my attempt to assign value and pass selected image back to images array
ChildComponent = () => (
<div>
<UploadButton
storage="menus"
value={uri => this.props.onImageSelect(uri)} //my greenness is really apparent here
onUploadComplete={uri => this.setState({images: uri})}
/>
//...
</div>
);
//added this function to the class
onImageSelect(uri) {
var el = this.state.images.concat(uri);
this.setState({
images: el
})
}
我知道我无法正确访问孩子。到目前为止,这是我处理的最复杂性。感谢您的时间。
在孩子/父级组件中编写 this.state
时,实际上是在访问页面状态。现在,我建议您像这样
children.push(<this.ChildComponent key={i} index={i}/>)
,每个孩子都只能处理自己的形象,例如So
ChildComponent = ({index}) => (
<div>
<UploadButton
storage="menus"
value={this.state.images[index]}
onUploadComplete={uri => {
let images = this.state.images.slice()
images[index] = uri
this.setState({images})
}}
/>
</div>
);