当前位置:  开发笔记 > 前端 > 正文

使用Redux + ReactRouter在React App中进行异步数据流?

如何解决《使用Redux+ReactRouter在ReactApp中进行异步数据流?》经验,为你挑选了1个好方法。

我正在使用Redux和React-router制作一个简单的Mail应用程序.由于我是Redux的新手,我不太了解Redux + Router中的实际数据流.

我想要的是什么

    在页面启动(/)之后,MailListComponent从服务器获取消息数组.此时不显示MessageComponent,因为它没有单个消息来为其获取数据.

    之后state.messages:[]被取出,应用程序被导航到的所述第一消息state.messages:[](/messages/1)`.

    转换完成后,将显示MessageComponent并获取id = 1 info的消息,并且它在单独的请求中是附件.

这是组件模型:

组件模型

我在做什么

// MailListActions.js
export function loadMessages() {
  return {
    type:    'LOAD_MESSAGES',
    promise: client => client.get('/messages')
  };
}

// MailListReducer.js
import Immutable from 'immutable';

const defaultState = { messages: [], fetchingMessages: false };

export default function mailListReducer(state = defaultState, action = {}) {
  switch (action.type) {
    case 'LOAD_MESSAGES_REQUEST':
      return state.merge({fetchingMessages: true});

    case 'LOAD_MESSAGES':
        return state.merge({fetchingMessages: false, messages: action.res.data || null});

    case 'LOAD_MESSAGES_FAILURE':
        // also do something

    default:
      return state;
  }
}

由于我使用promiseMiddleware,LOAD_MESSAGES,LOAD_MESSAGES_REQUEST并且LOAD_MESSAGES_FAILURE是作为请求dispacted /messages结束.

现在:

    可以loadMessages()MailListComponent的 componentDidMount中调度吗?

    如何过渡到/messages/1正确的?

    我应该activeMessageId在我的州创建吗?

    所有这些组件应如何与React-Router连接?

这是我目前的尝试:

export default (store) => {
  const loadAuth = (nextState, replaceState, next) => { ... };

  return (
    
       // <== THIS IS A DUMMY COMPONENT. It diplays pre-loader until the app is transitioned to real first message
      
    
  );
};

你能给我一些观点,如何连接点?什么是poper异步数据流逻辑?

我正在使用isomorphic-redux示例作为我的应用程序的基础.虽然是同构的,但正常的Redux app之间不应该有太大的区别

谢谢.

UPDATE

其中一个想法 - 设置onEnter挂钩,将获取消息,设置为状态和初始化转换.是redux +路由器的方式吗?

但是,这种方式也可能相当棘手,因为/messages只适用于经过身份验证的用户(其中store.getState().auth.get('loaded') == true)



1> Stijn de Wit..:

在我看来,服务器端渲染很重要.没有它,您将提供只在客户端生活的空白页面.它会严重影响你的SEO.因此,如果我们认为服务器端呈现很重要,我们需要一种方法来获取适合服务器端呈现的数据.

望着的文档服务器端渲染ICW反应路由器,这里是我们发现:

首先我们打电话match,传递当前位置和我们的路线

然后我们打电话ReactDOMServer.render,传递它renderProps我们得到的match

很明显,在进入渲染阶段之前,我们需要访问所获取的数据.

这意味着我们不能使用组件生命周期.我们也不能使用onEnter或任何其他仅在渲染已经开始时触发的钩子.在服务器端,我们需要渲染开始之前获取数据.这意味着我们需要能够确定什么,从获取renderProps我们从得到match.

常见的解决方案是fetchData在顶层组件上放置一个静态函数.在你的情况下,它可能看起来像这样:

export default class MailListComponent extends React.Component {
  static fetchData = (store, props) => {
    return store.dispatch(loadMessages());
  };
  // ....
}

我们可以fetchData在服务器端找到这个函数,并在继续渲染之前在那里调用它,因为match它给了我们renderProps包含匹配的组件类.所以我们可以循环遍历它们并获取所有fetchData函数并调用它们.像这样的东西:

var fetchingComponents = renderProps.components
  // if you use react-redux, your components will be wrapped, unwrap them
  .map(component => component.WrappedComponent ? component.WrappedComponent : component)
  // now grab the fetchData functions from all (unwrapped) components that have it
  .filter(component => component.fetchData);

// Call the fetchData functions and collect the promises they return
var fetchPromises = fetchingComponents.map(component => component.fetchData(store, renderProps));

fetchData返回结果store.dispatch,这将是一个Promise.在客户端,这将只显示一些loading屏幕,直到Promise完成,但在服务器端,我们将需要等到发生这种情况,所以当我们进入渲染阶段时,我们实际上在商店中有数据.我们可以用Promise.all它:

// From the components from the matched route, get the fetchData functions
Promise.all(fetchPromises)
  // Promise.all combines all the promises into one
  .then(() => {
    // now fetchData() has been run on every component in the route, and the
    // promises resolved, so we know the redux state is populated
    res.status(200);
    res.send('\n' +
      ReactDOM.renderToString(
        
      )
    );
    res.end();
})

你去吧 我们将完全填充的页面发送给客户端.在那里,我们可以使用onEnter或生命周期钩子或任何其他方便的方法来获取用户导航客户端时所需的后续数据.但是我们应该尝试确保我们在组件本身上有一个函数或注释(初始操作?),这样我们就可以预先获取服务器端渲染的数据.


我只想指出这是一个*mail*应用程序.这意味着搜索引擎无法访问**.所以SEO是一个有争议的问题.如果客户端无论如何都会渲染React组件......为什么要为它们提供预渲染页面呢?
推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有