2016-12-13 35 views
1

我有一个问题,弄清楚如何让反应组件具有基于异步获取数据的初始状态。 MyComponent从API获取数据,并通过Mobx action设置其内部data属性。使用Mobx异步加载组件数据服务器端

客户端,componentDidMount被调用并获取数据,然后设置并正确呈现。

import React from 'react'; 
import { observer } from 'mobx-react'; 
import { observable, runInAction } from 'mobx'; 

@observer 
export default class MyComponent extends React.Component { 
    @observable data = []; 

    async fetchData() { 
     loadData() 
      .then(results => { 
       runInAction(() => { 
        this.data = results; 
       }); 
      }); 
    } 

    componentDidMount() { 
     this.fetchData(); 
    } 

    render() { 
     // Render this.data 
    } 
} 

我知道在服务器上,componentDidMount没有被调用。

我有这样的事情对我的服务器:

import React from 'react'; 
import { renderToString } from 'react-dom/server'; 
import { useStaticRendering } from 'mobx-react'; 
import { match, RouterContext } from 'react-router'; 
import { renderStatic } from 'glamor/server' 
import routes from './shared/routes'; 

useStaticRendering(true); 

app.get('*', (req, res) => { 
    match({ routes: routes, location: req.url }, (err, redirect, props) => { 
     if (err) { 
      console.log('Error', err); 
      res.status(500).send(err); 
     } 

     else if (redirect) { 
      res.redirect(302, redirect.pathname + redirect.search); 
     } 

     else if (props) { 
      const { html, css, ids } = renderStatic(() => renderToString(<RouterContext { ...props }/>)); 

      res.render('../build/index', { 
       html, 
       css 
      }); 
     } 

     else { 
      res.status(404).send('Not found'); 
     } 
    }) 
}) 

我看过很多帖子,其中初始商店计算并通过Provider组件。我的组件被渲染,但它们的状态没有被初始化。我不想将这些数据保存在商店中,并希望它在本地范围内适用于某个组件。如何做呢 ?

回答

4

对于服务器端渲染,你需要首先获取你的数据,然后渲染。组件在SSR期间没有生命周期,只会呈现一次字符串,但无法响应任何未来更改。

由于您的datafetch方法是异步的,这意味着它不会影响输出,因为组件已经被写入。所以答案是首先获取数据,然后装载和渲染组件,而不使用任何异步机制(承诺,异步等)。我认为分离UI和数据获取逻辑是一个很好的实践(SSR,路由,测试),请参阅this blog

另一种方法是创建组件树,但请等待序列化,直到您的所有承诺都已解决。这是例如mobx-server-wait使用的方法。

+0

所以除了使用商店和初始化它没有其他的方法吗? – Komo

+0

是的,请参阅第二个链接 – mweststrate

+0

谢谢,我使用了第二种方法,使用https://github.com/ericclemmons/react-resolver – Komo