在呈现服务器端之前获取数据 [英] Fetching data before rendering server side

查看:90
本文介绍了在呈现服务器端之前获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我发现了 Este.js ,同构应用存在一些问题.我不明白如何在使用renderToString()呈现服务器端之前进行api调用.

Right now I'm discovering Este.js and I have a little issue with isomorphic apps. I don't understand how to make api call before rendering server side with renderToString().

一种解决方案是使用React Router在路由器级别进行所有数据提取.根据顶层路由,我可以预测将需要哪些数据,进行api调用,然后调用React.renderToString.

One solution consists in doing all the data fetching at the router level using React Router. Depending on the top level route, I can predict which data will be needed, make the api call, and then call React.renderToString.

太好了,但是我仍然必须在组件级别和路由器级别声明数据依赖关系.我最终写了两次相同的代码,但我不认为这是最好的方法.

Great, but I still have to declare the data dependencies at the component level AND in the router level. I end up writing the same code twice, and I don't believe it's the best way to do it.

好的,现在我可以做一些我想做的事情了.使用React-Router和此链接,我已经能够做到以下几点:

EDIT : Ok, for now I'm able to do somewhat what I want. Using React-Router and this link I've been able to made the following :

鉴于此全局应用程序状态,我想在指向/todos时预取待办事项

Giving this global app state, I want to prefetch todos when pointing /todos

{
  auth: {
    data: null,
    form: null
  },
  examples: {
    editable: {
      state: null,
      text: 'Some inline-editable text.'
    }
  },
  i18n: {
    formats: {},
    locales: initialLocale,
    messages: messages[initialLocale]
  },
  pendingActions: {},
  todos: {
    editables: {},
    newTodo: {
      title: ''
    },
    list: [{
      id: 1,
      title: 'first todo yipiyo'
    }]
  },
  users: {
    viewer: null
  }
}

todos.react.js

在待办事项组件中,我声明了静态函数fetchData.因为我想在我的appState中检索正确的密钥,所以我将'list'作为参数传递.感觉很脏.

todos.react.js

In todo component I declare a static function fetchData. Because I want to retrieve the correct key in my appState, I pass 'list' as a param. Feels dirty.

class Todos extends Component {

  static fetchData(){
    return actions.loadAllTodos('list');
  }

  componentDidMount(){
    Todos.fetchData();
  }

  render() {
    ...
  }

}

actions.js

Api通话和其他东西,我把钥匙传递给了诺言-感觉很hacky

actions.js

Api call and stuff, I pass the key to the promise - Feels hacky

export function loadAllTodos(key) {

  const promise = new Promise((resolve, reject) => {

    Api.get()
    .then(res => {
      res.key = key; //hacky time
      resolve(res)
    })
    .catch(err => {
      reject(err);
    })

  });

  return dispatch(loadAllTodos, promise);

}

render.js

router.run((Handler, routerState) => {

  var promise = Promise.all(routerState.routes
        .filter(route => route.handler.fetchData)
        .map(route => {
          return route.handler.fetchData();
        })
      );

  promise.then(resp => {

    console.log(resp);

    //Displays : 
    [ { id: 2, title: 'Im a second todo' },{ id: 3, title: 'I like todo' },
    cursor: 'list' ]

    //Some stuff to add resp to appState, using the correct key, yey iso+api=win
    appState = mergeThisWithMagic(appState, resp);

    const html = preloadAppStateThenRenderHtml(Handler, appState);
    const notFound = routerState.routes.some(route => route.name ===
      'not-found');
    const status = notFound ? 404 : 200;
    res.status(status).send(html);
    resolve();

  });


});

如您所见,我将创建一个函数来使用更新的todoList更新appState.

As you can see, I'll create a function to update appState with the updated todoList.

这样做可以吗?我想获得一些反馈,因为我感觉自己走的很暗:(.

Is this ok to do all of this ? I would like to have some feedback please, because I feel like I'm going in a dark path :(.

推荐答案

我在同构服务器端应用程序中完成了此任务,方法是将fetchData函数放入组件的statics对象中,并使用可以等到所有在将应用呈现为字符串之前,将返回数据.

I accomplished this in my isomorphic server side app by putting my fetchData functions in the statics object of the component(s) and using promises that wait until all the data is returned before rendering the app to string.

然后,您将通过prop将返回的数据向下传递到呈现的组件.这个例子对我开发这个应用程序很有帮助. React Router Mega Demo .

Then you would pass the returned data down to the rendered component via props. This example was instrumental in my development of this app. React Router Mega Demo.

这篇关于在呈现服务器端之前获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆