在React应用程序中使用Redux ReactRouter进行反应 – 异步数据流
我使用
Redux和
React-router制作一个简单的邮件应用程序。由于我比较新的Redux,我不太明白Redux Router的实际数据流。
我想要得到什么 >页面启动(/)后,MailListComponent从服务器中获取消息数组。此时,MessageComponent不显示,因为它没有单个消息来为其获取数据。 以下是组件模型: 我在做什么 // 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将被调度。 现在: >在MailListComponent的componentDidMount中调度loadMessages()可以吗? 这是我目前的尝试: export default (store) => { const loadAuth = (nextState,replaceState,next) => { ... }; return ( <Route name="app" component={App} path="/" onEnter={loadAuth}> <IndexRoute component={Content}/> // <== THIS IS A DUMMY COMPONENT. It diplays pre-loader until the app is transitioned to real first message <Route path="messages/:id" component={Message}/> </Route> ); }; 你能给我一些点,如何连接点?什么是poper异步数据流逻辑? 我正在使用isomorphic-redux示例作为我的应用程序的基础。虽然是同构的,但在正常的Redux应用程序之间不应该有太大的区别 谢谢。 UPDATE 其中一个想法 – 设置onEnter hook为< IndexRoute component = {Content} />,将获取消息,设置为状态和初始化转换。它是redux路由器的方式吗? 然而,这种方式也可能相当棘手,因为/消息仅适用于经过身份验证的用户(其中??store.getState()。auth.get(‘loaded’)== true)
在我看来,服务器端渲染很重要。没有它,你将会提供只在客户端生活的空白页面。这将严重影响您的SEO。所以,如果我们认为服务器端渲染很重要,我们需要一种方法来获取与服务器端渲染相匹配的数据。
看着the docs for server side rendering i.c.w. react-router,这是我们找到的: >首先我们称之为匹配,传递当前位置和路线 很明显,在进入渲染阶段之前,我们需要访问获取的数据。 这意味着我们不能使用组件生命周期。我们也不能使用onEnter或任何其他只在渲染已经开始时才触发的钩子。在服务器端,我们需要在渲染开始之前获取数据。这意味着我们需要能够确定从我们从匹配得到的renderProps中获取的内容。 常见的解决方案是在顶级组件上放置一个静态fetchData函数。在你的情况下,它可能看起来像这样: export default class MailListComponent extends React.Component { static fetchData = (store,props) => { return store.dispatch(loadMessages()); }; // .... } 我们可以在服务器端找到这个fetchData函数,然后在继续渲染之前调用它,因为匹配给了包含匹配组件类的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。 // 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('<!DOCTYPE html>n' + ReactDOM.renderToString( <Html lang="en-US" store={app.store} {...renderProps} script="/assets/bridalapp-ui.js" /> ) ); res.end(); }) 你去了我们向客户端发送一个完全填充的页面。在那里,我们可以使用onEnter或生命周期挂钩或任何其他方便的方法来获取用户在客户端导航时所需的后续数据。但是我们应该尝试确保我们在组件本身具有可用的功能或注释(初始操作?),以便我们可以预先为服务器端渲染提取数据。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |