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一点特殊用法
May 28 Javascript
javascript关于继承的用法汇总
Dec 20 Javascript
Linux下编译安装php libevent扩展实例
Feb 14 Javascript
JS实现在状态栏显示打字效果完整实例
Nov 02 Javascript
vue分页组件table-pagebar使用实例解析
Nov 15 Javascript
Node学习记录之cluster模块
May 31 Javascript
JS实现小球的弹性碰撞效果
Nov 11 Javascript
如何使用less实现随机下雪动画详解
Jan 02 Javascript
使用 vue 实例更好的监听事件及vue实例的方法
Apr 22 Javascript
vue配置nprogress实现页面顶部进度条
Sep 21 Javascript
vue实现pdf文档在线预览功能
Nov 26 Javascript
详解如何在Javascript中使用Object.freeze()
Oct 18 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的网址
2006/11/25 PHP
CodeIgniter php mvc框架 中国网站
2008/05/26 PHP
php 随机记录mysql rand()造成CPU 100%的解决办法
2010/05/18 PHP
smarty中先strip_tags过滤html标签后truncate截取文章运用
2010/10/25 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
模拟用户操作Input元素,不会触发相应事件
2007/05/11 Javascript
改善你的jQuery的25个步骤 千倍级效率提升
2010/02/11 Javascript
关于query Javascript CSS Selector engine
2013/04/12 Javascript
AngularJs ng-repeat 嵌套如何获取外层$index
2016/09/21 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
AngularJS $http模块POST请求实现
2017/04/08 Javascript
Js实现京东无延迟菜单效果实例(demo)
2017/06/02 Javascript
jQuery获取复选框选中的当前行的某个字段的值
2017/09/15 jQuery
React Native中Navigator的使用方法示例
2017/10/13 Javascript
JS精确判断数据类型代码实例
2019/12/18 Javascript
Python实现网站注册验证码生成类
2017/06/08 Python
用python标准库difflib比较两份文件的异同详解
2018/11/16 Python
Flask框架模板渲染操作简单示例
2019/07/31 Python
对Django 中request.get和request.post的区别详解
2019/08/12 Python
基于TensorFlow常量、序列以及随机值生成实例
2020/01/04 Python
jupyter notebook 恢复误删单元格或者历史代码的实现
2020/04/17 Python
python使用openpyxl操作excel的方法步骤
2020/05/28 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
2020/06/04 Python
详解scrapy内置中间件的顺序
2020/09/28 Python
CSS3绘制圆角矩形的简单示例
2015/09/28 HTML / CSS
幼教个人求职信范文
2013/12/02 职场文书
五一手机促销方案
2014/03/08 职场文书
机关节能减排实施方案
2014/03/17 职场文书
教师纪念9.18事件演讲稿范文
2014/09/14 职场文书
关于工作经历的证明书
2014/10/11 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
房地产置业顾问岗位职责
2015/04/11 职场文书
正能量励志演讲稿三分钟(范文)
2019/07/11 职场文书
导游词之西安骊山
2019/12/03 职场文书
Mysql事务索引知识汇总
2022/03/17 MySQL
Python爬虫 简单介绍一下Xpath及使用
2022/04/26 Python