我在父组件的循环中有一个反应子组件渲染。例如在父组件我有这样的:
<div className="md-grid">
{images
? images.map((img, index) => (
<PinnedImage
key={index}
name={img.mediaName}
picture={img.downloadURL}
imageSRC={this.createImageSrc(img.downlaodURL)}
onClick={this.downloadDoc.bind(
this,
img.downloadURL
)}
/>
))
: null}
</div>
我想在父级中调用一个函数,该函数使用REST端点对文件服务器进行授权fetch
请求。我在imageSRC
的{{1}}道具上调用该函数。以下是功能。
child component
我希望通过 async createImageSrc (url) {
console.log('createImageSrc called', { url })
if (url) {
const downlaodURL = `${PROTOCOL}${url}`
console.log({ downlaodURL })
const token = localStorage.getItem('access_token')
const headers = new Headers({ Authorization: `Bearer ${token}` })
const options = {
method: 'GET',
headers,
mode: 'cors',
cache: 'default'
}
const request = new Request(downlaodURL)
const finalResponse = await fetch(request, options).then(response => {
response.arrayBuffer().then(buffer => {
const base64Flag = 'data:image/jpeg;base64,'
const imageStr = this.arrayBufferToBase64(buffer)
const imageSRC = base64Flag + imageStr
console.log({ imageSRC })
return imageSRC
})
})
console.log({ finalResponse })
return finalResponse
}
}
arrayBufferToBase64 (buffer) {
let binary = ''
const bytes = [].slice.call(new Uint8Array(buffer))
bytes.forEach(b => {
binary += String.fromCharCode(b)
})
return window.btoa(binary)
}
将此createImageSrc
的结果作为PROPS
传递给子组件但是我没有达到预期效果。我究竟做错了什么?我被卡住了。
感谢
答案 0 :(得分:0)
您尝试在渲染方法中使用异步方法。
您想要做的是将来自呈现方法的createImageSrc
电话转移到componentDidUpdate
或componentDidMount
,然后将其设为createImageSrc
{1}}在完成提取时更新状态。
这是你应该做的伪代码
async function createImageSrc(url) {
const imageSRC = fetch();
return imageSRC;
}
class YourComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
imagesWithSrc: null
};
}
componentDidMount(props) {
if (props.images) {
this.fetchImageSrc(props.images);
}
}
fetchImageSrc = (images) => {
const promises = images.map((img) => createImageSrc(img.downloadURL));
Promise.all(promises).then((...imageSRCs) => {
const newImages = images.map((img, idx) => {
return {
...img,
imageSRC: imageSRCs[idx]
};
});
this.setState({ imagesWithSrc: newImages });
});
}
render() {
const { imagesWithSrc } = this.state;
return (
<div className="md-grid">
{ imagesWithSrc
? imagesWithSrc.map((img, index) => (
<PinnedImage
key={index}
name={img.mediaName}
picture={img.downloadURL}
imageSRC={img.imageSRC}
onClick={this.downloadDoc.bind(
this,
img.downloadURL
)}
/>
))
: null}
</div>
);
}
}
附注只是想让你知道你在一些地方拼写 downloadURL 错误
答案 1 :(得分:0)
问题是子组件不知道什么时候会履行承诺。当承诺履行时,您将告诉子组件。
如果您正在使用redux添加图像加载来存储每个孩子可以在重新渲染时获取其来源的位置。
<div className="md-grid">
{images
? images.map((img, index) => (
<PinnedImage
key={index}
id={index[or some other unique id]}
name={img.mediaName}
picture={img.downloadURL}
imageSRC={this.createImageSrc(img.downlaodURL,id[same id used as child id])}
onClick={this.downloadDoc.bind(
this,
img.downloadURL
)}
/>
))
: null}
</div>
async createImageSrc (url,id) {
console.log('createImageSrc called', { url })
if (url) {
const downlaodURL = `${PROTOCOL}${url}`
console.log({ downlaodURL })
const token = localStorage.getItem('access_token')
const headers = new Headers({ Authorization: `Bearer ${token}` })
const options = {
method: 'GET',
headers,
mode: 'cors',
cache: 'default'
}
const request = new Request(downlaodURL)
const finalResponse = await fetch(request, options).then(response => {
response.arrayBuffer().then(buffer => {
const base64Flag = 'data:image/jpeg;base64,'
const imageStr = this.arrayBufferToBase64(buffer)
const imageSRC = base64Flag + imageStr
console.log({ imageSRC })
this.props.dispatch ({type:"imageLoaded",payload:{src:imageSRC,id:id}})
// return imageSRC
})
})
console.log({ finalResponse })
return finalResponse
}
}
arrayBufferToBase64 (buffer) {
let binary = ''
const bytes = [].slice.call(new Uint8Array(buffer))
bytes.forEach(b => {
binary += String.fromCharCode(b)
})
return window.btoa(binary)
}