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 相关文章推荐
jquery animate 动画效果使用说明
Nov 04 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
Javascript setInterval的两种调用方法(实例讲解)
Nov 29 Javascript
js实现仿百度瀑布流的方法
Feb 05 Javascript
jQuery post数据至ashx实例详解
Nov 18 Javascript
求js数组的最大值和最小值的四种方法
Mar 03 Javascript
angularJS之$http:与服务器交互示例
Mar 17 Javascript
jquery引入外部CDN 加载失败则引入本地jq库
May 23 jQuery
小程序实现带年月选取效果的日历
Jun 27 Javascript
写一个Vue Popup组件
Feb 25 Javascript
微信小程序template模版的使用方法
Apr 13 Javascript
Vue记住滚动条和实现下拉加载的完美方法
Jul 31 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获取随机数字和字母的方法详解
2013/06/06 PHP
Tab页界面,用jQuery及Ajax技术实现
2009/09/21 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
2013/04/12 Javascript
简体中文转换繁体中文(实现代码)
2013/12/25 Javascript
jQuery的deferred对象详解
2014/11/12 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
JavaScript使用shift方法移除素组第一个元素实例分析
2015/04/06 Javascript
JavaScript节点及列表操作实例小结
2015/08/05 Javascript
基于JavaScript制作霓虹灯文字 代码 特效
2015/09/01 Javascript
Javascript中replace()小结
2015/09/30 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
2015/11/30 Javascript
jQuery日历插件datepicker用法详解
2016/03/03 Javascript
React实现双向绑定示例代码
2016/09/19 Javascript
smartupload实现文件上传时获取表单数据(推荐)
2016/12/12 Javascript
nodejs密码加密中生成随机数的实例代码
2017/07/17 NodeJs
js 提取某()特殊字符串长度的实例
2017/12/06 Javascript
基于JavaScript实现简单的音频播放功能
2018/01/07 Javascript
vue devtools的安装与使用教程
2018/08/08 Javascript
深入理解Antd-Select组件的用法
2020/02/25 Javascript
vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】
2020/06/01 Javascript
初学Python函数的笔记整理
2015/04/07 Python
Python处理PDF及生成多层PDF实例代码
2017/04/24 Python
简单实现python画圆功能
2018/01/25 Python
Python使用pickle模块储存对象操作示例
2018/08/15 Python
pandas数据集的端到端处理
2019/02/18 Python
python打印n位数“水仙花数”(实例代码)
2019/12/25 Python
Python中os模块功能与用法详解
2020/02/26 Python
Python能做什么
2020/06/02 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
需要知道的CSS3动画技术
2010/01/01 HTML / CSS
基于Canvas+Vue的弹幕组件的实现
2019/07/23 HTML / CSS
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
英国景点门票网站:attractiontix
2019/08/27 全球购物
巧克力蛋糕店创业计划书
2014/01/14 职场文书
汽车检测与维修专业求职信
2014/07/04 职场文书
我去timi了,一起去timi是什么意思?
2022/04/13 杂记