【发布时间】:2019-07-29 13:13:00
【问题描述】:
我是新手,所以请原谅我。我在理解状态时遇到问题,特别是儿童的状态。
目的:我正在尝试创建一个用户可以附加越来越多组件的表单——在本例中是图像。
会发生什么:用户附加 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
})
}
我知道我没有正确访问 child 道具。这是迄今为止我处理过的最复杂的问题。感谢您的宝贵时间。
【问题讨论】:
-
TLDR 您是否考虑过将父级中的所有图像保存在一个数组中并遍历它以创建子级。
-
@Miro J。我认为在某处放置一组图像,
constructor或ParentComponent,将是一个解决方案。我不知道该怎么做:用户点击UploadButton,选定的图像被放入一个图像数组中,然后遍历数组创建所有的孩子。目前,用户在选择图像之前附加孩子。我在某处听说程序员 90% 的时间都在花时间,而不是打字,而是盯着电脑屏幕思考如何实现他们的想法,我已经体验了三天。 -
Google“如何在反应中从子组件调用父函数” > 在子组件中创建一个函数,用于在上传完成后将图像传输到父组件。父数组最多应该有一个“空”元素,它将在子数组中显示上传功能。
-
@Miro J。我正在尝试实施您现在的建议。我感觉问题的一部分是因为我使用的是无状态组件,所以我编辑了很多代码。
标签: reactjs firebase react-native firebase-storage