加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – 如何在客户端和服务器端呈现逻辑上将react-router和r

发布时间:2020-12-15 05:07:35 所属栏目:百科 来源:网络整理
导读:我希望我的基于React的SPA能够在服务器端呈现(这些日子不是这样).因此,我想将React与 react-router,redux和一些构建层(如 isomorphic starterkit)结合起来. 有hapi universal redux连在一起,但我正在努力如何组织我的流程.我的数据来自REST API的多个端点.不
我希望我的基于React的SPA能够在服务器端呈现(这些日子不是这样).因此,我想将React与 react-router,redux和一些构建层(如 isomorphic starterkit)结合起来.

有hapi universal redux连在一起,但我正在努力如何组织我的流程.我的数据来自REST API的多个端点.不同的组件具有不同的数据需求,应该及时在客户端上加载数据.在服务器上,必须获取特定路由(组件集)的所有数据,并将必要的组件呈现给字符串.

在我的第一种方法中,我使用redux的中间件来创建异步操作,这些操作加载数据,返回一个promise,并在promise解析时触发SOME_DATA_ARRIVED操作. Reducers然后更新我的商店,组件重新渲染,一切都很好.原则上,这是有效的.但后来我意识到,在路由发挥作用的那一刻,流程变得尴尬.

列出许多数据记录的某个组件具有多个用于过滤记录的链接.每个过滤后的数据集都应该通过它自己的URL提供,例如/ filter-by /:filter.所以我使用不同的< Link to = {...}>用于在单击时更改URL并触发路由器的组件.路由器应根据当前URL表示的状态更新存储,这反过来导致相关组件的重新呈现.

这不容易实现.我首先尝试使用componentWillUpdate来触发一个操作,该操作异步加载我的数据,填充存储并为我的组件引起另一个重新渲染周期.但这不适用于服务器,因为只支持3种生命周期方法.

所以我正在寻找正确的方法来组织这个.用户与应用程序的交互(从用户角度更改应用程序状态)应更新URL. IMO这应该使路由器以某种方式加载必要的数据,更新商店,并开始对帐过程.

所以互动 – >网址更改 – >数据提取 – >商店更新 – >重新渲染.

这种方法也应该在服务器上工作,因为从请求的URL开始,应该能够确定要加载的数据,生成初始状态并将该状态传递给redux的存储生成.但我找不到妥善做到这一点的方法.所以对我来说,出现以下问题:

>我的方法是错误的,因为有些东西我不明白/不知道吗?
>在redux的商店中保持从REST API加载数据是正确的吗?
>在redux商店中保留状态的组件和其他人通过自己管理状态是不是有点尴尬?
>是否有互动的想法 – >网址更改 – >数据提取 – >商店更新 – >重新渲染完全错了?

我愿意接受各种建议.

我今天确实设置了完全相同的东西.我们已经拥有的是react-router和redux.我们模块化了一些模块,将东西注入其中 – 而中提琴 – 它起作用.我用 https://github.com/erikras/react-redux-universal-hot-example作为参考.

部分:

router.js

我们返回一个函数(位置,历史,存储)来使用promises设置路由器. routes是包含所有组件的react-router的路由定义.

module.exports = function (location,history,store) {
    return new Bluebird((resolve,reject)  => {
        Router.run(routes,location,(Handler,state) => {
            const HandlerConnected = connect(_.identity)(Handler);
            const component = (
                <Provider store={store}>
                    {() => <HandlerConnected />}
                </Provider>
            );
            resolve(component);
        }).catch(console.error.bind(console));
    });
};

2. store.js

您只需将初始状态传递给createStore(reducer,initialState).您只需在服务器和客户端上执行此操作.对于客户端,您应该通过脚本标记(即窗口.__ initialstate__)使状态可用.
有关更多信息,请参见http://rackt.github.io/redux/docs/recipes/ServerRendering.html.

3.在服务器上呈现

获取数据,使用该数据设置初始状态(…数据).上面的createRouter = router.js. res.render表示使用以下内容渲染玉石模板

script.
    window.csvistate.__initialstate__=!{initialState ? JSON.stringify(initialState) : 'null'};
...
#react-start
    != html
var initialState = { ...data };
var store = createStore(reducer,initialState);
createRouter(req.url,null,store).then(function (component) {
    var html = React.renderToString(component);
    res.render('community/neighbourhood',{ html: html,initialState: initialState });
});

4.适应客户

然后你的客户可以做同样的事情.位置可以是React-Router的HistoryLocation

const initialState = window.csvistate.__initialstate__;
const store = require('./store')(initialState);

router(location,store).then(component => {
    React.render(component,document.getElementsByClassName('jsx-community-bulletinboard')[0]);
});

回答你的问题:

>你的方法似乎是对的.我们也这样做.人们甚至可以将网址作为州的一部分.> redux商店内的所有州都是好事.这样你就有了一个单一的事实来源.>我们现在还在研究应该去哪里.目前我们在服务器上请求componentDidMount上的数据应该已经存在.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读