Next.js实现react服务器端渲染的方法示例


Posted in Javascript onJanuary 06, 2019

说明

实现 路由跳转、redux

文件版本

  • “next”: “^4.2.3”,
  • “react”: “^16.2.0”,
  • “react-dom”: “^16.2.0”

Next.js GitHub 文档

项目源码

使用

Next.js 使用文件体统作为API,可以自动进行服务器端渲染和代码分割

1. 安装

yarn add next react react-dom

2. package.json 中添加 npm script

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
 },

3. 创建 /pages 文件夹,其中文件会映射为路由

/pages 文件夹是顶级组件文件夹 其中 /pages/index.js 文件会映射文 / 路由,其他文件根据文件名映射

目录结构 映射路由
/pages/index.js /
/pages/about.js /about
/pages/home/index.js /home
/pages/home/about.js /home/about

每一个路由js文件都会 export 一个 React 组件,这个组件可以是函数式的也可以是通过集成 React.Component 得到的类

export default () => <div>this is index page </div>;

4. 创建 /static 文件夹,存放静态资源

静态资源文件夹文件会映射到 /static/ 路由下,直接通过 http://localhost:3000/static/test.png 访问

5. 使用内置组件 <head> 定制每个页面的 head 部分

import Head from 'next/head'; // 引入内置组件

  export default () => (
    <div>
     <Head>
       <title>index page</title>
       <meta name="viewport" content="initial-scale=1.0, width=device-width"/>
     </Head>
     <div>this is index page</div>
    </div>
  );

6. 使用内置组件 <Link> 进行路由跳转

import Link from 'next/link';

  export default () => (
    <div>
     <p>this is home index page</p>
     <Link href="/about" rel="external nofollow" rel="external nofollow" >
       <a> to about page</a>
     </Link>
    </div>
  );

更多 Link 使用方式

import React, {Component} from 'react';
import Link from 'next/link';

export default class About extends Component {
  constructor(props) {
   super(props);
  }
  render() {
   // href 值可以是一个对象
   const href = {
     pathname: '/home',
     query: {name: 'test'}
   };

   return (
    <div>
      <p>this is about page </p>
      <img src="/static/test.png" alt="test"/>
      {/* replace 覆盖历史跳转 */}
      <Link href={href} replace>
      <a>click to home index page</a>
      </Link>
    </div> 
   );
  }
}

7. 使用内置 router 方法,手动触发路由跳转

next/router 提供一套方法和属性,帮助确认当前页面路由参数,和手动触发路由跳转

import router from 'next/router';
  /*
    router.pathname ==> /home
    router.query ==> {}
    router.route - 当前路由
    asPath - 显示在浏览器地址栏的实际的路由
    push(url, as=url) - 跳转页面的方法
    replace(url, as=url) - 跳转页面
  */

更好的方式使用路由 ? router 的 withRouter 方法

import Link from 'next/link';
import {withRouter} from 'next/router';

const Home = (props) => {
  // 这里的 props 会得到 {router, url} 两个属性
  // router: {push: ƒ, replace: ƒ, reload: ƒ, back: ƒ, prefetch: ƒ, …}
  // url: {query: {…}, pathname: "/home", asPath: "/home?name=test", back: ƒ, push: ƒ, …}
  console.log(props);
  return (
   <div>
     <p>this is home index page </p>
     {/* <Link href="/about" rel="external nofollow" rel="external nofollow" >
      <a> to about page</a>
     </Link> */}
   </div>
  );
}

export default withRouter(Home);

8. 使用 next-redux-wrapper 插件辅助实现 redux

1. 安装依赖

sudo yarn add next-redux-wrapper redux react-redux redux-devtools-extension redux-thunk

2. 创建 initializeStore.js 一个可以返回 store 实例的函数

在这个文件中会完成装载中间件、绑定reducer、链接浏览器的redux调试工具等操作

import { createStore, applyMiddleware } from 'redux';
  import { composeWithDevTools } from 'redux-devtools-extension'; 
  import thunk from 'redux-thunk';
  import reducer from '../modules/reducers';

  const middleware = [thunk];
  const initializeStore = initialState => {
    return createStore(
       reducer, 
       initialState, 
       composeWithDevTools(applyMiddleware(...middleware))
     );
  };

  export default initializeStore;

3. 创建 reducer , action

与普通 react-redux 项目创建 reducer, action 的方法一致,我把这部分代码都提取到一个名为 modules的文件夹中

// /modules/reducers.js
  import { combineReducers } from 'redux';
  import about from './about/reducer';

  // 合并到主reducer
  const reducers = {
    about
  };

  // combineReducers() 函数用于将分离的 reducer 合并为一个 reducer 
  export default combineReducers(reducers);
// /modules/about/reudcer.js 
  // /about 页面的 reducer
  import {
    CHANGE_COUNT
  } from '../types-constant';

  const initialState = {
    count: 0
  };

  const typesCommands = {
    [CHANGE_COUNT](state, action) {
     return Object.assign({}, state, { count: action.msg });
    },
  }

  export default function home(state = initialState, action) {
    const actionResponse = typesCommands[action.type];

    return actionResponse ? actionResponse(state, action) : state;
  }
// /modules/about/actions.js
  // /about 页面的 action
  import {
    CHANGE_COUNT
  } from '../types-constant';

  export function changeCount(newCount) {
    return {
     type: CHANGE_COUNT,
     msg: newCount
    };
  }

4. 页面中使用

需要用到 next-redux-wrapper 提供的 withRedux 高阶函数,以及 react-redux 提供的 connect 高阶函数

import React, { Component } from 'react';
  import withRedux from 'next-redux-wrapper';
  import { connect } from 'react-redux';
  import { bindActionCreators } from 'redux';
  import AboutCom from '../components/About/index';
  import initializeStore from '../store/initializeStore';
  import { changeCount } from '../modules/about/actions';

  class About extends Component {
    constructor(props) {
     super(props);
    }
    render() {
     const { about: { count }, changeCount } = this.props;
     return <AboutCom count={count} changeCount={changeCount} />;
    }
  }

  const connectedPage = connect(
    state => ({ about: state.about }),
    dispatch => ({
     changeCount: bindActionCreators(changeCount, dispatch)
    })
  )(About);

  export default withRedux(initializeStore)(connectedPage);

 更多

查看 github官网

react-next github上一个next架构为主实现React服务端渲染的模板

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Knockoutjs快速入门(经典)
Dec 24 Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 Javascript
javascript中的绑定与解绑函数应用示例
Jun 24 Javascript
使用jquery解析XML示例代码
Sep 05 Javascript
JavaScript中textRange对象使用方法小结
Mar 24 Javascript
Vue.JS入门教程之处理表单
Dec 01 Javascript
简单几步实现返回顶部效果
Dec 05 Javascript
使用JavaScript实现表格编辑器(实例讲解)
Aug 02 Javascript
node.js使用express框架进行文件上传详解
Mar 03 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
May 07 Javascript
解决Vue router-link绑定事件不生效的问题
Jul 22 Javascript
Antd表格滚动 宽度自适应 不换行的实例
Oct 27 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
Jan 06 #Javascript
Bootstrap4 gulp 配置详解
Jan 06 #Javascript
jQuery实现获取当前鼠标位置并输出功能示例
Jan 05 #jQuery
node.js连接mysql与基本用法示例
Jan 05 #Javascript
Node.js Buffer模块功能及常用方法实例分析
Jan 05 #Javascript
Node.js net模块功能及事件监听用法分析
Jan 05 #Javascript
JS无限级导航菜单实现方法
Jan 05 #Javascript
You might like
PHP详解ASCII码对照表与字符转换
2011/12/05 PHP
解析isset与is_null的区别
2013/08/09 PHP
关于php内存不够用的快速解决方法
2013/10/26 PHP
destoon网站转移服务器后搜索汉字出现乱码的解决方法
2014/06/21 PHP
php计算给定时间之前的函数用法实例
2015/04/03 PHP
CakePHP框架Session设置方法分析
2017/02/23 PHP
PHP数据分析引擎计算余弦相似度算法示例
2017/08/08 PHP
php7函数,声明,返回值等新特性介绍
2018/05/25 PHP
JavaScript基本编码模式小结
2012/05/23 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/20 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
2015/08/30 Javascript
JAVASCRIPT代码编写俄罗斯方块网页版
2015/11/26 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
详解AngularJs中$resource和restfu服务端数据交互
2016/09/21 Javascript
Ajax异步文件上传与NodeJS express服务端处理
2017/04/01 NodeJs
如何自定义微信小程序tabbar上边框的颜色
2019/07/09 Javascript
bootstrap-table后端分页功能完整实例
2020/06/01 Javascript
js实现贪吃蛇游戏(简易版)
2020/09/29 Javascript
Web服务器框架 Tornado简介
2014/07/16 Python
浅谈DataFrame和SparkSql取值误区
2018/06/09 Python
python实现顺序表的简单代码
2018/09/28 Python
浅谈python脚本设置运行参数的方法
2018/12/03 Python
Python面向对象实现一个对象调用另一个对象操作示例
2019/04/08 Python
python异步Web框架sanic的实现
2020/04/27 Python
Python实现手势识别
2020/10/21 Python
马来西亚最好的婴儿商店:Motherhood
2017/09/14 全球购物
美国滑板店:Tactics
2020/11/08 全球购物
30年同学聚会感言
2014/01/30 职场文书
小学教师师德师风自我剖析材料
2014/09/29 职场文书
大学学生个人总结
2015/02/15 职场文书
城南旧事观后感
2015/06/11 职场文书
医院消毒隔离制度
2015/08/05 职场文书
Python opencv缺陷检测的实现及问题解决
2021/04/24 Python
使用golang编写一个并发工作队列
2021/05/08 Golang
利用Python判断整数是否是回文数的3种方法总结
2021/07/07 Python