视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Next.js实现react服务器端渲染的方法示例
2020-11-27 22:02:22 责编:小采
文档


说明

实现 路由跳转、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="https://www.gxlcms.com/static/test.png" 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服务端渲染的模板

    下载本文
    显示全文
    专题