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 相关文章推荐
javascript 三种方法实现获得和设置以及移除元素属性
Mar 20 Javascript
Js判断CSS文件加载完毕的具体实现
Jan 17 Javascript
js强制把网址设为默认首页
Sep 29 Javascript
解析Node.js异常处理中domain模块的使用方法
Feb 16 Javascript
JavaScript省市区三级联动菜单效果
Sep 21 Javascript
利用vue写todolist单页应用
Dec 15 Javascript
easyui下拉框动态级联加载的示例代码
Nov 29 Javascript
VUE重点问题总结
Mar 19 Javascript
Vue项目history模式下微信分享爬坑总结
Mar 29 Javascript
微信小程序可滑动月日历组件使用详解
Oct 21 Javascript
vue Tab切换以及缓存页面处理的几种方式
Nov 05 Javascript
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
Feb 04 jQuery
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
centos 5.6 升级php到5.3的方法
2011/05/14 PHP
Trying to clone an uncloneable object of class Imagic的解决方法
2012/01/11 PHP
奇怪的PHP引用效率问题分析
2012/03/23 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
2017/08/25 PHP
php转换上传word文件为PDF的方法【基于COM组件】
2019/06/10 PHP
不一样的文字闪烁 轮番闪烁
2009/11/11 Javascript
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
Juqery Html(),append()等方法的Bug解决方法
2010/12/13 Javascript
一个挺有意思的Javascript小问题说明
2011/09/26 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
AngularJS入门教程之表单校验用法示例
2016/11/02 Javascript
Windows系统下安装Node.js的步骤图文详解
2016/11/15 Javascript
bootstrap-datetimepicker实现只显示到日期的方法
2016/11/25 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
jquery在vue脚手架中的使用方式示例
2017/08/29 jQuery
详解node nvm进行node多版本管理
2017/10/21 Javascript
js如何获取访问IP、地区、当前操作浏览器
2019/07/23 Javascript
[01:45]IMBATV TI4前线报道-选手到达
2014/07/07 DOTA
python生成随机mac地址的方法
2015/03/16 Python
Python实现的微信好友数据分析功能示例
2018/06/21 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
python中metaclass原理与用法详解
2019/06/25 Python
Python之修改图片像素值的方法
2019/07/03 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
python获取时间戳的实现示例(10位和13位)
2020/09/23 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
英国排名第一的LED灯泡网站:LED Bulbs
2019/09/03 全球购物
团结就是力量演讲稿
2014/05/21 职场文书
2014机关干部学习“焦裕禄精神”思想汇报
2014/09/19 职场文书
校园会短篇的广播稿
2014/10/21 职场文书
2015教师年度工作总结范文
2015/04/07 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书
python套接字socket通信
2022/04/01 Python
Python 视频画质增强
2022/04/28 Python