作品:
render() {
const storageRef = firebase.storage().ref();
const nice = Object.keys(this.state.photos).map((key) => {
return <div>{key}</div>;
});
return(
{nice}
)
不起作用:
render() {
const storageRef = firebase.storage().ref();
const nice = Object.keys(this.state.photos).map((key) => {
storageRef.child('front.jpg').getDownloadURL().then(function(url) {
return <div><img src={url} /></div>;
)}
});
return(
{nice}
)
.then
东西似乎破坏了 React 中的渲染。我可以看到 nice
在控制台中一切正常,但 DOM 上没有任何结果。代码的想法是在状态中存储图像名称(引用 Firebase 存储中的图像),然后在使用 getDownloadURL
获取 URL 后渲染每个图像。
最佳答案
Promise 是异步的。上面的代码每次都会返回 {nice},因为在等待履行 promise 时,将返回下一行代码,即 return ({nice}),这将是未定义的。一般来说,在渲染方法中做出 promise 是不好的做法。事实上,理想情况下,你的整个组件将是一个纯函数(即它只是根据它接收到的 props 进行渲染,并且异步内容在其他地方处理,例如在 redux thunk 或 saga 中,但我们将在一点。
处理组件内异步代码的正确方法是使用react的lifecycle methods 。反过来,使用生命周期方法需要将组件定义为扩展 React.Component 的类(请参阅链接)。将异步函数(promise)放入哪个生命周期方法取决于您何时需要运行异步代码。例如,如果您只想在首次呈现组件时运行代码,则可能需要使用“componentWillMount”方法,甚至仅使用构造函数。例如,像这样:
class MyComponent extends React.Component {
constructor(props){
this.state = {
photoUrl: ''
}
storageRef.child('front.jpg').getDownloadURL().then(function(url) {
this.setState({photoUrl: url})
)}
}
render(){
if(this.state.photoUrl){
return (<div><img src={this.state.url} /></div>)
} else {
return '' //will return nothing until you actually have a url
}
}
}
promise 只会在组件首次呈现时运行一次。为了获得更大的灵 active ,请查看生命周期方法。如果您希望异步代码运行以响应用户交互,请定义您自己的函数来容纳 Promise 并在完成时更新状态。然后在您的 html 元素中,像这样引用该函数:
<input ... onClick={this.myAsyncFn.bind(this)}/>
好吧,回到我所说的有关 redux 的内容。您现在可能不需要它,但是当您继续沿着 React 开发的道路前进时,您肯定会需要它。根据您所说的使用 Firebase 作为商店的标题,我猜您可能不完全理解 redux 商店的用途。它是一个状态管理解决方案。你为什么需要这个?例如,如果另一个组件需要您刚刚检索到的 URL,该怎么办?它也必须进行异步调用吗?您可以有一个更高级别的组件来进行异步调用并通过 props 将 url 传递给其子组件,但如果这对您的应用程序没有真正意义怎么办?此外,如果您的用户需要导航到该组件不存在的其他页面,但该其他页面也需要该 url,该怎么办?还需要再去拿吗?对 Firebase 进行如此多的调用并不是很高效,所以如果我们只放置与我们正在工作的状态(例如“appIsBusy”标志)和数据(例如我们正在跟踪的 url)相关的所有需要的内容会怎么样?全部集中在一处?这就是 redux 存储。 Redux thunk 和 redux sagas 只是处理所有异步事物(以及其他事物,但现在不用担心)的方法,这些事物可能以组件外部的方式发生在您的应用程序中。这意味着您的组件都可以是纯函数,只需接受 props 并根据给定的内容进行渲染。它们本身不需要执行任何异步操作,并且始终会按可预测的方式运行。也就是说,我的建议是查看 redux 库(here)并尝试将其与您的应用程序集成(您还需要react-redux 库。This is a helpful article 以更好地了解其中发生的情况)。还不用担心 thunk 或 sagas,只需使用上面所示的生命周期方法处理组件中的异步内容即可。然后,当您掌握了所有这些后,您就可以开始研究 thunk 和 sagas。
关于javascript - 基于 React 中的 Promise 呈现元素(Firebase 存储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46812325/