React服务端渲染探秘:3.同构项目中引入Redux

栏目: IOS · Android · 发布时间: 4年前

内容简介:这一节主要是讲述Redux如何被引入到同构项目中以及其中需要注意的问题。重新回顾一下redux的运作流程:再回顾一下同构的概念,即在React代码客户端和服务器端各自运行一遍。

这一节主要是讲述Redux如何被引入到同构项目中以及其中需要注意的问题。

重新回顾一下redux的运作流程:

React服务端渲染探秘:3.同构项目中引入Redux

再回顾一下同构的概念,即在React代码客户端和服务器端各自运行一遍。

一、创建全局store

现在开始创建store。 在项目根目录的store文件夹(总的store)下:

import {createStore, applyMiddleware, combineReducers} from 'redux';
import thunk from 'redux-thunk';
import { reducer as homeReducer } from '../containers/Home/store';
//合并项目组件中store的reducer
const reducer = combineReducers({
  home: homeReducer
})
//创建store,并引入中间件thunk进行异步操作的管理
const store = createStore(reducer, applyMiddleware(thunk));

//导出创建的store
export default store
复制代码

二、组件内action和reducer的构建

Home文件夹下的工程文件结构如下:

React服务端渲染探秘:3.同构项目中引入Redux

在Home的store目录下的各个文件代码示例:

//constants.js
export const CHANGE_LIST = 'HOME/CHANGE_LIST';
复制代码
//actions.js
import axios from 'axios';
import { CHANGE_LIST } from "./constants";

//普通action
const changeList = list => ({
  type: CHANGE_LIST,
  list
});
//异步操作的action(采用thunk中间件)
export const getHomeList = () => {
  return (dispatch) => {
    return axios.get('xxx')
      .then((res) => {
        const list = res.data.data;
        console.log(list)
        dispatch(changeList(list))
      });
  };
}
复制代码
//reducer.js
import { CHANGE_LIST } from "./constants";

const defaultState = {
  name: 'sanyuan',
  list: []
}

export default (state = defaultState, action) => {
  switch(action.type) {
    default:
      return state;
  }
}
复制代码
//index.js
import  reducer  from "./reducer";
//这么做是为了导出reducer让全局的store来进行合并
//那么在全局的store下的index.js中只需引入Home/store而不需要Home/store/reducer.js
//因为脚手架会自动识别文件夹下的index文件
export {reducer}
复制代码

三、组件连接全局store

下面是Home组件的编写示例。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getHomeList } from './store/actions'

class Home extends Component {
  render() {
    const { list } = this.props
    return list.map(item => <div key={item.id}>{item.title}</div>)
  }
}

const mapStateToProps = state => ({
  list: state.home.newsList,
})

const mapDispatchToProps = dispatch => ({
  getHomeList() {
    dispatch(getHomeList());
  }
})
//连接store
export default connect(mapStateToProps, mapDispatchToProps)(Home);
复制代码

对于store的连接操作,在同构项目中分两个部分,一个是与客户端store的连接,另一部分是与服务端store的连接。都是通过react-redux中的Provider来传递store的。

客户端:

//src/client/index.js
import React from 'react';
import ReactDom from 'react-dom';
import {BrowserRouter, Route} from 'react-router-dom';
import { Provider } from 'react-redux';
import store from '../store'
import routes from '../routes.js'

const App = () => {
  return (
    <Provider store={store}>
      <BrowserRouter>
        {routes}
      </BrowserRouter>
    </Provider>
  )
}

ReactDom.hydrate(<App />, document.getElementById('root'))
复制代码

服务端:

//src/server/index.js的内容保持不变
//下面是src/server/utils.js
import Routes from '../Routes'
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom'; 
import { Provider } from 'react-redux';
import React from 'react'

export const render = (req) => {
  const content = renderToString(
    <Provider store={store}>
      <StaticRouter location={req.path} >
        {Routes}
      </StaticRouter>
    </Provider>
  );
  return `
    <html>
      <head>
        <title>ssr</title>
      </head>
      <body>
        <div id="root">${content}</div>
        <script src="/index.js"></script>
      </body>
    </html>
  `
}
复制代码

四、潜在的坑

其实上面这样的store创建方式是存在问题的,什么原因呢?

上面的store是一个单例,当这个单例导出去后,所有的用户用的是同一份store,这是不应该的。那么这么解这个问题呢?

在全局的store/index.js下修改如下:

//导出部分修改
export default  () => {
  return createStore(reducer, applyMiddleware(thunk))
}
复制代码

这样在客户端和服务端的js文件引入时其实引入了一个函数,把这个函数执行就会拿到一个新的store,这样就能保证每个用户访问时都是用的一份新的store。


以上所述就是小编给大家介绍的《React服务端渲染探秘:3.同构项目中引入Redux》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Namo Webeditor5.5一看就懂.

Namo Webeditor5.5一看就懂.

吳聲毅 / 金禾資訊 / 20040214 / NT$ 169

一看就懂系列書全以初學者的角度切入,全書以STEP BY STEP方式撰寫,並以豐富的圖片搭配教學,在最後更加上日常生活實例運用講解,一路學來一氣呵成。為了增進學習的效率更採用高級紙品全彩印刷,這麼好的書,您還在等什麼,一看就懂系列書保證是您最佳入門學習好伙伴。 本書特色: 1、一看就懂:Step by Step操作詳盡說明、讓您一看就懂 2、精選範例:精彩實務範例生動活......一起来看看 《Namo Webeditor5.5一看就懂.》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具