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 相关文章推荐
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
Sep 20 Javascript
jQuery插件原来如此简单 jQuery插件的机制及实战
Feb 07 Javascript
javascript中typeof的使用示例
Dec 19 Javascript
jQuery实现购物车数字加减效果
Mar 14 Javascript
基于jquery实现省市联动效果
Nov 23 Javascript
jQuery webuploader分片上传大文件
Nov 07 Javascript
vue图片加载与显示默认图片实例代码
Mar 16 Javascript
从零开始学习Node.js系列教程六:EventEmitter发送和接收事件的方法示例
Apr 13 Javascript
javascript ES6 新增了let命令使用介绍
Jul 07 Javascript
详解最新vue-cli 2.9.1的webpack存在问题
Dec 16 Javascript
JS判断数组里是否有重复元素的方法小结
May 21 Javascript
在Layui中操作数据表格,给指定单元格添加事件示例
Oct 26 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图片验证码代码
2008/03/27 PHP
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
PHP使用flock实现文件加锁的方法
2015/07/01 PHP
PHP Echo字符串的连接格式
2016/03/07 PHP
php实现搜索类封装示例
2016/03/31 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
php session_decode函数用法讲解
2019/05/26 PHP
PHP 与 js的通信(via ajax,json)
2010/11/16 Javascript
用Javascript评估用户输入密码的强度(Knockout版)
2011/11/30 Javascript
深入理解JS中的变量及作用域、undefined与null
2014/03/04 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
2015/03/03 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
微信小程序switch开关选择器使用详解
2018/01/31 Javascript
深入理解Vue nextTick 机制
2018/04/28 Javascript
vue-cli在 history模式下的配置详解
2019/11/26 Javascript
js实现无刷新监听URL的变化示例代码详解
2020/06/03 Javascript
[01:33:59]真人秀《加油 DOTA》 第六期
2014/09/09 DOTA
详解Python编程中基本的数学计算使用
2016/02/04 Python
基础的十进制按位运算总结与在Python中的计算示例
2016/06/28 Python
举例讲解Python中metaclass元类的创建与使用
2016/06/30 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
appium+python adb常用命令分享
2020/03/06 Python
Python多线程Threading、子线程与守护线程实例详解
2020/03/24 Python
python如何快速拼接字符串
2020/10/28 Python
如何用 Python 处理不平衡数据集
2021/01/04 Python
Python实现一个论文下载器的过程
2021/01/18 Python
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
美国Rue La La闪购网站:奢侈品、中高档品牌限时折扣
2016/10/19 全球购物
德国BA保镖药房韩文网:kr.ba.de
2017/09/04 全球购物
MIXIT官网:俄罗斯最大的化妆品公司之一
2020/01/25 全球购物
2014年小学植树节活动方案
2014/03/02 职场文书
餐饮服务食品安全责任书
2014/07/25 职场文书
女方家长婚礼致辞
2015/07/27 职场文书
导游词之沈阳清昭陵
2019/12/28 职场文书
Python 操作pdf pdfplumber读取PDF写入Exce
2022/08/14 Python