根据React(Firebase存储)中的Promise更新元素

时间:2017-10-18 14:15:07

标签: 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后呈现每个图像。

2 个答案:

答案 0 :(得分:0)

您需要在渲染函数中返回单个元素包装。

所以它应该是

return (<div>{photosArray}</div>)

你也有一个拼写错误,数组同时用作:photosArray和photosarray

答案 1 :(得分:0)

Promise是异步的。上面的代码每次都会返回{nice},因为当promise等待完成时,将返回下一行代码,即return({nice}),这将是未定义的。在你的渲染方法中设置一个承诺通常是不好的做法。事实上,理想情况下,你的整个组件将是一个纯函数(即它只是基于它接收的道具渲染,异步的东西在其他地方处理,比如在redux thunk或saga中,但我们会回到那个一点点。

在组件中处理异步代码的正确方法是使用react lifecycle methods。反过来,使用生命周期方法需要将组件定义为扩展React.Component的类(请参阅链接)。将异步函数(promise)放入哪种生命周期方法取决于何时需要运行异步代码。例如,如果您只是希望代码在首次呈现组件时运行,您可能希望使用&#34; componentWillMount&#34;方法甚至只是构造函数。例如,像这样:

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只会运行一次。为了获得更大的灵活性,请查看生命周期方法。如果您希望异步代码运行以响应用户交互,请定义您自己的函数,该函数包含承诺并在完成时更新状态。然后在你的html元素中,像这样引用该函数:

<input ... onClick={this.myAsyncFn.bind(this)}/>

好的,回到我对redux所说的话。你现在可能不需要它,但是当你继续沿着这条反应发展的道路前进时,你肯定会想要它。根据您所说的使用Firebase作为商店的标题,我猜你可能无法完全理解redux商店的用途。这是一个州管理解决方案。你为什么需要这个?那么,例如,如果另一个组件需要您刚刚检索到的URL,该怎么办?它也必须进行异步调用吗?您可以使用更高级别的组件进行异步调用,并通过道具将URL传递给其子项,但如果这对您的应用程序没有意义呢?此外,如果您的用户需要导航到该组件不存在的其他页面,但该页面上还需要该URL,该怎么办?你需要再去一次吗?向Firebase拨打这么多电话并不是非常有效,所以如果我们把所有我们需要的东西都放到我们的状态(比如#34; appIsBusy&#34;旗帜)和数据(比如我们保留的网址)怎么办?跟踪我们在一个地方合作?那是redux商店。 Redux thunk和redux sagas只是处理所有异步事物(以及其他东西,但现在不用担心)的方式,这可能会在您的应用程序中以组件外部的方式发生。这意味着你的组件都可以是纯函数,只需要根据它们给出的东西来获取道具和渲染。他们自己不需要做任何异步,并且总是可以预测。也就是说,我的建议是查看redux库(here)并尝试将其与您的应用程序集成(您还需要react-redux库。This is a helpful article以更好地理解什么是接下来)。不要担心thunks或sagas,只需使用如上所示的生命周期方法处理组件中的异步内容。然后,当你掌握了所有这些,你就可以开始研究thunk和sagas了。