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 相关文章推荐
[转]JS宝典学习笔记
Feb 07 Javascript
JavaScript学习笔记(一) js基本语法
Oct 25 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
Nov 14 Javascript
js下将金额数字每三位一逗号分隔
Feb 19 Javascript
javascript实现数组去重的多种方法
Mar 14 Javascript
jQuery中用on绑定事件时需注意的事项
Mar 19 Javascript
vue2.0模拟锚点的实例
Mar 14 Javascript
详解vue 项目白屏解决方案
Oct 31 Javascript
vue响应式系统之observe、watcher、dep的源码解析
Apr 09 Javascript
gulp构建小程序的方法步骤
May 31 Javascript
微信小程序canvas截取任意形状的实现代码
Jan 13 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
Jun 04 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中循环语句的用法介绍
2012/01/30 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
php实现的数字验证码及数字运算验证码
2015/07/30 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
2016/09/21 PHP
Yii CDBCriteria常用方法实例小结
2017/01/19 PHP
使用PHPStorm+XDebug搭建单步调试环境
2017/11/19 PHP
Js中sort()方法的用法
2006/11/04 Javascript
JS 创建对象(常见的几种方法)
2008/11/03 Javascript
浅析Js中的单引号与双引号问题
2013/11/06 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
浅谈javascript六种数据类型以及特殊注意点
2013/12/20 Javascript
被遗忘的javascript的slice() 方法
2015/04/20 Javascript
js实现网页图片延时加载 提升网页打开速度
2016/01/26 Javascript
js获取iframe中的window对象的实现方法
2016/05/20 Javascript
jQuery实现表格元素动态创建功能
2017/01/09 Javascript
javascript 判断一个对象为数组的方法
2017/05/03 Javascript
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
微信小程序页面间跳转传参方式总结
2019/06/13 Javascript
在Python的setuptools框架下生成egg的教程
2015/04/13 Python
简单解析Django框架中的表单验证
2015/07/17 Python
python结合shell查询google关键词排名的实现代码
2016/02/27 Python
深入理解Python装饰器
2016/07/27 Python
python使用fcntl模块实现程序加锁功能示例
2017/06/23 Python
Python基础知识点 初识Python.md
2019/05/14 Python
Python3使用xlrd、xlwt处理Excel方法数据
2020/02/28 Python
tensorflow使用CNN分析mnist手写体数字数据集
2020/06/17 Python
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
eBay德国站:eBay.de
2017/09/14 全球购物
工作决心书范文
2014/03/11 职场文书
事业单位竞聘上岗实施方案
2014/03/28 职场文书
项目经理任命书范本
2014/06/05 职场文书
中职毕业生自我鉴定
2014/09/13 职场文书
三提三创主题教育活动查摆整改措施
2014/10/25 职场文书
关于感恩的素材句子(38句)
2019/11/11 职场文书
nginx请求限制配置方法
2021/07/09 Servers