使用Reactjs从客户端上的文件数组渲染图像
我是一个新的反应,我正在实施一个多文件上传系统。我已经通过按钮上的点击事件处理程序实现了用户驱动的文件选择,该按钮将所选文件添加到数组中 出于某种原因,每当我选择一个文件时,控制台中会显示以下错误,导致应用程序停止工作: 未捕获不变冲突:对象作为子对象无效 找到:[对象承诺]。如果要呈现一组 子级,请改用数组 作为参考,此功能的我的界面如下所示: 以下是我的组件实现的相关部分:使用Reactjs从客户端上的文件数组渲染图像,reactjs,file,file-upload,Reactjs,File,File Upload,我是一个新的反应,我正在实施一个多文件上传系统。我已经通过按钮上的点击事件处理程序实现了用户驱动的文件选择,该按钮将所选文件添加到数组中 出于某种原因,每当我选择一个文件时,控制台中会显示以下错误,导致应用程序停止工作: 未捕获不变冲突:对象作为子对象无效 找到:[对象承诺]。如果要呈现一组 子级,请改用数组 作为参考,此功能的我的界面如下所示: 以下是我的组件实现的相关部分: state = { selectedPortifolio: {}, portflioFiles: [] }
state = {
selectedPortifolio: {},
portflioFiles: []
}
在文件onchange事件上调用此方法
loadPortfolio = (e) => {
if (e.target.files) {
this.setState({
selectedPortifolio: {
file: e.target.files[0],
filename: e.target.files[0].name
}
});
}
};
当单击add按钮时,将调用此方法
addPortfolio = () => {
if (
this.state.selectedPortifolio &&
this.state.selectedPortifolio.file
) {
let items = this.state.portflioFiles;
items.push(this.state.selectedPortifolio);
this.setState({ selectedPortifolio: {}, portflioFiles: items });
console.log(this.state.portflioFiles);
}
};
所有这些之后,我将这个数组加载到div中
{this.state.portflioFiles.length > 0 ? (
this.state.portflioFiles.map((item, index) => {
return (
<div className="portfolio-file" key={index}>
{getDataURL(item.file).then((data) => {
return (
<image
src={data}
alt={item.filename}
/>
);
})}
</div>
);
})
) : (
<div></fdv>
)}
目前,您的代码正试图通过调用getDataURL函数映射portfolioItems来直接呈现promise对象。目前,React基于同步渲染,这意味着React目前不可能实现基于承诺的渲染
为了实现您所需要的,考虑解决GETDATAURL在AdppDebug中的呈现逻辑IE之外返回的承诺。 这需要对组件状态进行扩展,以保存由getDataURL返回的承诺解析的图像数据。然后,您需要更新组件的渲染逻辑,以便从当前处于组件状态的图像数据渲染图像:
更新状态形状 更新addPortfolio 更新渲染逻辑希望有帮助 所以我在用户单击add按钮时将文件转换为dataurl?是的,这是正确的,您希望将promise/async代码转移到click事件处理程序中,然后使用支持渲染所需的数据更新组件状态,以便渲染不需要基于async/promise的函数callsRC,但图像已损坏。我很抱歉,我的回答中有一个小错误。请参阅在更新的渲染逻辑中使用imageSrc。这有用吗?
export const getDataURL = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
};
state = {
selectedPortifolio: {},
portflioFiles: [],
portflioImages : [] // Extend state with arrage for image data
}
addPortfolio = () => {
if (
this.state.selectedPortifolio &&
this.state.selectedPortifolio.file
) {
let items = this.state.portflioFiles;
let images = this.state.portflioImages;
items.push(this.state.selectedPortifolio);
// Resolve promise outside of render-logic. Once data
// required for rendering is available, update state
// to trigger a re-render
getDataURL(this.state.selectedPortifolio).then((image) => {
this.setState({
selectedPortifolio: {},
portflioFiles: items,
// Add resolved image to portflioImages images array
portflioImages : images.concat([image])
});
});
}
};
{this.state.portflioImages.length > 0 ? (
/* map portflioImages directly to image without promise */
this.state.portflioImages.map((imageSrc, index) => {
return (
<div className="portfolio-file" key={index}>
<img src={imageSrc} alt={item.filename} />
</div>
);
})
) : (
<div></fdv>
)}