javascript - 基于 React 中的 Promise 呈现元素(Firebase 存储)

标签 javascript reactjs firebase firebase-storage

作品:

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/

相关文章:

javascript - Grep 获取图像 URL

javascript - 尝试使用 jQuery remove() 函数删除选择框

javascript - 使用代理访问自定义元素的数据集

javascript - 从子进程执行node.js中的代码

ios - 尝试Pod安装Firebase时出现Cocoapods错误-Nanaimo

javascript - 如何获得与数组相同的结果但没有第三个括号?

reactjs - 如何使用 enzyme 通过 onClick 测试 redux Action

reactjs - Material ui 数据网格复选框行选择不起作用

javascript - 如何在 React.JS 中使用多个值过滤数据

android - 检查 Firebase 存储中是否存在某个名称的文件夹