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 ready函数源代码研究
Dec 06 Javascript
基于jquery的分页控件(C#)
Jan 06 Javascript
常用jQuery选择器总结
Jul 11 Javascript
JavaScript indexOf方法入门实例(计算指定字符在字符串中首次出现的位置)
Oct 17 Javascript
javascript的列表切换【实现代码】
May 03 Javascript
IONIC自定义subheader的最佳解决方案
Sep 22 Javascript
Websocket 向指定用户发消息的方法
Jan 09 Javascript
JS代码检查工具ESLint介绍与使用方法
Feb 04 Javascript
js中switch语句的学习笔记
Mar 25 Javascript
vue实现整屏滚动切换
Jun 29 Javascript
vue treeselect获取当前选中项的label实例
Aug 31 Javascript
vue实现点击按钮“查看详情”弹窗展示详情列表操作
Sep 09 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下实现伪 url 的超简单方法[转]
2007/09/24 PHP
Yii框架where查询用法实例分析
2019/10/22 PHP
基于jquery的15款幻灯片插件
2011/04/10 Javascript
jQuery内容过滤选择器用法示例
2016/09/09 Javascript
微信小程序(应用号)开发新闻客户端实例
2016/10/24 Javascript
jQuery基于xml格式数据实现模糊查询及分页功能的方法
2016/12/25 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
详解Nodejs之npm&amp;package.json
2017/06/15 NodeJs
js实现加载页面就自动触发超链接的示例
2017/08/31 Javascript
vue引用js文件的多种方式(推荐)
2018/05/17 Javascript
node.js调用C++函数的方法示例
2018/09/21 Javascript
如何实现双向绑定mvvm的原理实现
2019/05/28 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
vue实现购物车的监听
2020/04/20 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
2020/05/10 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
[06:21]2014DOTA2国际邀请赛 庆祝VG首阶段领跑;B叔为挣牛排半夜整理情报
2014/07/13 DOTA
通过Python爬虫代理IP快速增加博客阅读量
2016/12/14 Python
Python实现改变与矩形橡胶的线条的颜色代码示例
2018/01/05 Python
PyQt5每天必学之创建窗口居中效果
2018/04/19 Python
python  Django中的apps.py的目的是什么
2018/10/15 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
Python 导入文件过程图解
2019/10/15 Python
Python 私有化操作实例分析
2019/11/21 Python
Python利用全连接神经网络求解MNIST问题详解
2020/01/14 Python
Python项目跨域问题解决方案
2020/06/22 Python
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
标准化管理实施方案
2014/02/25 职场文书
公立医院改革实施方案
2014/03/14 职场文书
社区平安建设汇报材料
2014/08/14 职场文书
作风建设年活动实施方案
2014/10/24 职场文书
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
丧事答谢词
2015/01/05 职场文书
会议接待欢迎词范文
2015/01/26 职场文书
《家》读后感:万惜拯救,冷暖自知
2019/09/25 职场文书
Python基础知识学习之类的继承
2021/05/31 Python