ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

react-ssr之redux使用

2019-06-09 08:51:33  阅读:346  来源: 互联网

标签:actions ssr react import redux store reducers


作为全家桶之一,必须要有啊。必须的必啊

  • 安装redux(这个我就不说了,自己去npm找)

仓库的基本配置

  • 在src目录下新增store目录
  • 在store目录下创建index.js, actions-types.js actions 目录, reducers目录
  • src/store/index.js
import { createStore, applyMiddleware } from 'redux'
import saga from 'redux-saga'
import logger from 'redux-logger'
import reducers from './reducers'
// 注意:因为服务端和客户端store不一样,所以分别创建,后期会看到代码不同处理
export function getServerStore () {
    return createStore(
        reducers,
        applyMiddleware(saga, logger)
    )
}


export function getClientStore () {
    return createStore(
        reducers,
        applyMiddleware(saga, logger)
    )
}

// 
  • 创建actions-typeas
export const INCREMENT = 'INCREMENT'
  • 创建reducers, 使用index导出reducers, 单独定义每一个组建的reduces
//src/store/reducers/index.js 中导出counter
import { combineReducers } from 'redux'
import counter from './counter'

let resucers = combineReducers({
    counter
})

export default resucers
  • 新增src/store/reducers/counter.js文件,内容如下
import * as types from '../action-types'

let initState = {
    number: 0
}

export default function (state = initState, action) {
    switch (action.type) {
        case types.INCREMENT:
        let {number} = state
        return {number: ++number}
    default:
        return state;
    }
}

  • 在src/store/reducers/actions目录中新建counter.js, 然后定义actions
// 计数器的基本配置
import * as types from '../action-types'
export default {
    increment () {
        return {type: types.INCREMENT}
    }
}

引入store

  • 客户端的配置
import React, {Fragment} from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import routers from '../routes'
import Header from '../components/Header'
import { Provider } from 'react-redux' // 配合使用redux
import { getClientStore } from '../store' // 导入store

// hydrate 表示把服务端渲染未完成的工作完成,比如绑定事件完成
ReactDOM.hydrate(
<Provider store={getClientStore()}>
<BrowserRouter>
    <Fragment>
        <Header />
        <div className="container" style={{marginTop: 70}}>
            {routers}
        </div>
    </Fragment>
</BrowserRouter>
</Provider>, document.getElementById('root'))
  • 服务端的配置
// src/server/index.js
const Koa = require('koa')
const _ = require('koa-route');
import render from './render'

let app = new Koa()
// 设置服务端静态目录
app.use(require('koa-static')('public'))
// 这里路径改为*, 不管哪个路径,都组走这里
app.use(_.get('*', render))

app.listen(3000, () => {
    console.log('server start at 3000')
})

// src/server/render.js
import { StaticRouter } from 'react-router-dom'
import Header from '../components/Header'
import routes from '../routes'
import React, {Fragment} from 'react'
import {renderToString} from 'react-dom/server'
import { Provider } from 'react-redux'
import { getServerStore } from '../store'

export default  function (ctx, next) {
    let context = {}
    let store = getServerStore()
    let html = renderToString(
        <Provider store={store}>
            <StaticRouter context={{}} location={ctx.req.url}>
                <Fragment>
                    <Header />
                    <div className="container" style={{marginTop: 70}}>
                        {routes}
                    </div>
                </Fragment>
            </StaticRouter>
        </Provider>
    )
    ctx.body = `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    </head>
    <body>
        <div id="root">${html}</div>
        <script src="/client.js"></script>
    </body>
    </html>
    `
}
  • counter中使用store
import React from 'react'
import { connect } from "react-redux"
import actions from '../../store/actions/counter'

class Counter extends React.Component{
    state = {number: 0}
    render () {
        return (<div style={{textAlign: 'center'}}>
            <p>{this.props.number}</p>
            <button onClick={this.props.increment}>+</button>
        </div>)
    }
}
// 连接store
const WrapCounter = connect(
    state => state.counter,
    actions
)(Counter)
export default WrapCounter

总结

上边是实现redux的基本过程,这里再总结一下思路

  1. 在src目录下创建store目录

  2. 在store目录下创建index.js, actions-types.js actions 目录, reducers目录

  3. 创建actions-typeas

  4. 创建reducers, 使用index导出reducers, 单独定义每一个组建的reduces

  5. 在服务端和客户端配置redux的基本代码

  6. counter中使用store

完整代码

标签:actions,ssr,react,import,redux,store,reducers
来源: https://blog.csdn.net/weixin_33768153/article/details/91350164

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有