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中的对象和数组的应用技巧
Jan 07 Javascript
JavaScript中为元素加上name属性的方法
May 09 Javascript
capacityFixed 基于jquery的类似于新浪微博新消息提示的定位框
May 24 Javascript
解析JavaScript中的不可见数据类型
Dec 02 Javascript
JavaScript中的原型prototype完全解析
May 10 Javascript
JS拉起或下载app的实现代码
Feb 22 Javascript
vue中appear的用法
Aug 17 Javascript
vue实现样式之间的切换及vue动态样式的实现方法
Dec 19 Javascript
vue组件实现可搜索下拉框扩展
Oct 23 Javascript
Nuxt配合Node在实际生产中的应用详解
Aug 07 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
Aug 10 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具体实现代码
2010/10/12 PHP
PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
2014/06/23 PHP
浅谈PHP中单引号和双引号到底有啥区别呢?
2015/03/04 PHP
PHP反射实际应用示例
2019/04/03 PHP
PHP rsa加密解密算法原理解析
2020/12/09 PHP
JavaScript中诡异的delete操作符
2015/03/12 Javascript
JavaScript制作简易的微信打飞机
2015/03/31 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
jQuery.each使用详解
2015/07/07 Javascript
高效利用Angular中内置服务$http、$location等
2016/03/22 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
2016/09/14 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
js控制按钮,防止频繁点击响应的实例
2017/02/15 Javascript
微信小程序实现红包雨功能
2018/07/11 Javascript
Vue 路由 过渡动效 数据获取方法
2018/07/31 Javascript
使用FormData实现上传多个文件
2018/12/04 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
vue实现搜索功能
2019/05/28 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
使用vue实现通过变量动态拼接url
2020/07/22 Javascript
python使用xlrd模块读写Excel文件的方法
2015/05/06 Python
Python单元测试实例详解
2018/05/25 Python
Python实现基于KNN算法的笔迹识别功能详解
2018/07/09 Python
对python中的argv和argc使用详解
2018/12/15 Python
Python使用crontab模块设置和清除定时任务操作详解
2019/04/09 Python
Python3爬虫里关于Splash负载均衡配置详解
2020/07/10 Python
CSS3实现的文本3D效果附图
2014/09/03 HTML / CSS
CSS3 实现的火焰动画
2020/12/07 HTML / CSS
英国最大的线上保健品零售商之一:Vitamin Planet
2016/12/01 全球购物
JAKO-O德国野酷台湾站:德国首屈一指的婴幼童用品品牌
2019/01/14 全球购物
学生手册家长评语
2014/02/10 职场文书
软件项目实施计划书
2014/05/02 职场文书
科技之星事迹材料
2014/06/02 职场文书
地震慰问信
2015/02/14 职场文书
2015年办公室主任工作总结
2015/04/09 职场文书
tensorflow中的数据类型dtype用法说明
2021/05/26 Python