next.js 集成redux

在使用next.js 我们有一部分数据,是需要同步到服务端环境的,在页面到达浏览器之前,redux就应该填充一部分数据

其他框架参考, nuxt.js vuex 某个只在服务端初始化执行的action函数

首先建立仓库文件 store/index.js

import { combineReducers, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
import user from './reducers/user'
import config from './reducers/config'
import anchor from './reducers/anchor';
import router from './reducers/router';
//每个redux已经单独分开,如果在初始化需要单独初始化某个模块的数据,需要这样合并,详情看redux文档
const combined = (state = {}, action) => {
  return {
    user: user(state?.user, action), 
    config: config(state?.config, action),
    router: router(state?.router, action),
    anchor: anchor(state?.anchor, action)
  };
}
//这里为了在服务端创建时,初始化一遍redux
const createNextStore = (init) => createStore(combined, init, composeWithDevTools());

export default createNextStore

建立withRedux 用于结合redux和app

import createNextStore from "./index";
import { getUserInfo, getAnchorPage } from '@/service/live';
import dayJs from 'dayjs';
import React from 'react'
const __NEXT_REDUX_STORE = "__NEXT_REDUX_STORE"; //定义个变量用来查看客户端是否存在store

//根据不同场景进行创建或者返回现有store
function getOrCreateStore (initialState) {
  const isServer = typeof window === "undefined";
  if (isServer) {
    // 服务端
    // 返回新的store
    return createNextStore(initialState);
  }

  if (!window[__NEXT_REDUX_STORE]) {
    // console.log('XXX')
    // 是客户端客户端没有store create
    window[__NEXT_REDUX_STORE] = createNextStore(initialState);
  }
  return window[__NEXT_REDUX_STORE];
}
const withRedux = (Comp) => {
  // 高阶组件,让每个app都经历高阶组件进行处理集成redux
  return class HocReducerComp extends React.Component {
    constructor(props) {
      super(props);
      this.ReduxStore = getOrCreateStore(props.initialState);
    }
    static async getInitialProps (ctx) {
      let user = {
      }

      let anchor = {
      }
      //尝试在服务端先获取用户信息,在注入到客户端
      try {
        //尝试获取用户信息

        if (ctx.ctx.req?.cookies['app-access-token']) {
          const code = ctx.ctx.req.cookies['app-access-token'] || ""
          user.info = await getUserInfo({
            headers: {
              "app-access-token": code
            }
          })
          user.info['app_access_token'] = code
          user.info = { ...user?.info, registerDay: dayJs().diff(dayJs(user?.info?.createTime), 'day') || 0, }
          if (user?.info?.roomId) {
            const c = await getAnchorPage({
              headers: {
                "app-access-token": code
              }
            })
            const { host = {}, ...other } = c;
            anchor.anchorInfo = { ...host, ...other }
          }
        }
      } catch (error) {
        console.log(error)
      }
      const MyStore = getOrCreateStore({ anchor, user });
      /* 利用ctx把store传入App,在App中进行store的初始化 */
      ctx.ReduxStore = MyStore;
      let appProps = {};
      if (typeof Comp.getInitialProps === 'function') {
        appProps = await Comp.getInitialProps(ctx);
      }
      // 这里都是在服务端重新注入数据
      return { ...appProps, initialState: MyStore.getState() };
    }
    render () {
      return <Comp {...this.props} ReduxStore={this.ReduxStore} />;
    }
  }
};
export default withRedux;

_app.js 合并

import 'normalize.css';
import '../styles/main.scss';
import { Provider } from "react-redux";
import withRedux from "@/store/withRedux"
import App from 'next/app'
function nextApp ({ Component, pageProps, ReduxStore }) {

  return (
    <Provider store={ReduxStore}>
      <Component {...pageProps} />
    </Provider>
  )
}

nextApp.getInitialProps = async (ctx) => {
  const appProps = await App.getInitialProps(ctx);
  //ctx.ReduxStore 
  return { ...appProps };
};

export default withRedux(nextApp)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值