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不是基础的基础
Dec 24 Javascript
js 单引号 传递方法
Jun 22 Javascript
JQuery 学习笔记 选择器之四
Jul 23 Javascript
JavaScript 格式字符串的应用
Mar 29 Javascript
读jQuery之十一 添加事件核心方法
Jul 31 Javascript
原生js的弹出层且其内的窗口居中
May 14 Javascript
JavaScript中的Math.LOG2E属性使用详解
Jun 14 Javascript
jquery使整个div区域可以点击的方法
Jun 24 Javascript
js判断复选框是否选中及选中个数的实现代码
May 30 Javascript
完全深入学习Bootstrap表单
Nov 28 Javascript
jQuery Validate设置onkeyup验证的实例代码
Dec 09 Javascript
打字效果动画的4种实现方法(超简单)
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+AJAX聊天程序[聊天室]提供下载
2007/07/21 PHP
以文件形式缓存php变量的方法
2015/06/26 PHP
PHP按指定键值对二维数组进行排序的方法
2015/12/22 PHP
php版微信公众平台之微信网页登陆授权示例
2016/09/23 PHP
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
ASP.NET中AJAX 调用实例代码
2012/05/03 Javascript
JavaScript调试技巧之console.log()详解
2014/03/19 Javascript
单击某一段文字改写文本颜色
2014/06/06 Javascript
jQuery结合CSS制作动态的下拉菜单
2015/10/27 Javascript
JavaScript 数组some()和filter()的用法及区别
2016/05/20 Javascript
javascript 闭包详解及简单实例应用
2016/12/31 Javascript
JavaScript两个变量交换值的实现方法
2017/03/01 Javascript
ReactNative实现Toast的示例
2017/12/31 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
Layui表格监听行单双击事件讲解
2019/11/14 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
2020/07/21 Javascript
详解如何在Javascript中使用Object.freeze()
2020/10/18 Javascript
使用Vant完成通知栏Notify的提示操作
2020/11/11 Javascript
[00:11]战神迅矛
2019/03/06 DOTA
深入理解python try异常处理机制
2016/06/01 Python
基于python时间处理方法(详解)
2017/08/14 Python
解决Python安装后pip不能用的问题
2018/06/12 Python
matlab中二维插值函数interp2的使用详解
2020/04/22 Python
Python实现手绘图效果实例分享
2020/07/22 Python
Python持续监听文件变化代码实例
2020/07/22 Python
AmazeUI的JS表单验证框架实战示例分享
2020/08/21 HTML / CSS
亚洲在线旅行门户网站:Expedia.com.hk(智游网)
2020/04/14 全球购物
信息技术教学反思
2014/02/12 职场文书
车间安全生产标语
2014/06/06 职场文书
先进员工获奖感言
2014/08/14 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
2016大学自主招生推荐信范文
2015/03/23 职场文书
2016七夕情人节寄语
2015/12/04 职场文书
《田忌赛马》教学反思
2016/02/19 职场文书
Vue2项目中对百度地图的封装使用详解
2022/06/16 Vue.js