如何在反应同构应用程序中渲染之前获取服务器中的数据?

时间:2017-07-02 19:21:21

标签: reactjs

我找到了一些方法,但是他们没有使用react-router版本4.这真的很奇怪,在文档中没有关于它的任何信息。

6 个答案:

答案 0 :(得分:1)

事情一定发生了变化,但在2015年我写了一篇关于此事的文章。你可以阅读它here

主要想法是将您的行动包装成承诺。服务器端必须调用相应的操作(取决于路由)并等待承诺完成,然后再调用React.renderToString()(这是同步的)。然后,您需要找到一种方法来同步服务器计算的状态与客户端,以避免对任何内容执行相同的请求。在文章中,我解释了我将状态传递给窗口对象。

但同样是在2015年,它可能已经过时了。

答案 1 :(得分:1)

https://blog.tableflip.io/server-side-rendering-with-react-and-redux/ - 我在阅读本文后解决了我的问题。

答案 2 :(得分:1)

在2019年回答此问题,因为似乎尚无明确答案。

如果后端服务使用的是GraphQL,则实际上您可以只使用react-apollo,然后可以在组件本身中声明数据要求。 SSR的过程非常简单,因为react-apollo仅提供renderToStringWithData()getDataFromTree()之类的功能来自动获取组件树中的所有数据。

但是,如果您不使用graphql,而只是简单的获取GET请求,那么我认为没有像react-apollo这样的解决方案。最近,我为此用例编写了react-isomorphic-data。您可以在每个组件本身内部声明组件的数据要求,并且它还提供SSR支持的功能,类似于react-apollo

图书馆还很年轻,但是我认为值得尝试。如果您有反馈意见,请随时在github上提出问题。

答案 3 :(得分:0)

您可以看到我的react-ssr-startkit

客户端:

class Home extends React.Component {
// some logic
}
Home.serverFetch = {type: 'repos/fetchData'};

服务器:

routes
.filter(route => matchPath(req.url, route))
.map(route => route.component)
.filter(comp => comp.serverFetch)
.map(comp => {
    const {type, payload} = comp.serverFetch;
    return dispatch({type, payload});
});

答案 4 :(得分:-1)

您需要获取网络服务器上的数据,然后将数据传递给您的(哑)组件,该组件只会呈现而不会产生太多逻辑。

如果您需要更新客户端上的数据,请查看套接字解决方案或仅在componentdidmount()中创建间隔提取。

我们目前正在研究这个问题,并且我们正在使用Airbnb的Hypernova来处理通用渲染,问题是您仍然需要一个网络服务器来允许组件使用我们可以使用的网址进行映射缓存和服务器端包含在我们的页面中。 因此,在该网络服务器中,您可以执行获取和传递,因此您可以将组件的初始状态视为html。

答案 5 :(得分:-2)

您可以在构造函数中使用axios,根据反应Lifecycles,构造函数在render()之前;

示例:

  constructor(props) {
    super(props);
    this.state = {
      items: [],
    };
    axios.get('http://into-the-feed-api.cloud.globoi.com/') 
    .then(res => {
      const index = this.getIndex(res.data);
      if (index) {
        this.setState({
          items: [res.data[index]].concat(res.data.slice(0, index).concat(res.data.slice(index + 1, res.data.length)) ),
        });
      } else {
        this.setState({ items: res.data }); 
      } 
    });
    this.changeHeaderExpanded = this.changeHeaderExpanded.bind(this);
  }