1

所有源代码、文档和图片都在 github 的仓库里,点击进入仓库

相关阅读

1. 404 页面

  • 404 页面需要客户端告诉服务端,这个页面是否匹配到了,如果没有匹配到,该如何操作,所以我们还是需要使用 StaticRouter 的 context 属性来传递数据
  • 所以,我们先新建一个 404 的组件,/src/containers/NotFound/index.js
  • 这里对 staticContext 的定义时添加一个 NotFound 为 true 的属性,服务端拿到这个属性,可以知道是否是进入到了 404 页面
  • 新建 404 组件 /src/containers/NotFound/index.js
// /src/containers/NotFound/index.js
import React, { Component } from 'react';

class NotFound extends Component {

  componentWillMount() {
    const { staticContext } = this.props;
    staticContext && (staticContext.NotFound = true);
  }

  render() {
    return (
      <div>404 NotFound</div>
    );
  }
}

export default NotFound;
  • 添加路由 /src/routes.js
export default [
  {
    path: '/',
    component: App,
    key: 'app',
    routes: [
      {
        path: '/',
        component: Home,
        loadData: Home.loadData,
        exact: true,
        key: '/'
      },
      {
        path: '/news',
        component: News,
        exact: true,
        key: '/news'
      },
      {
        component: NotFound
      }
    ]
  }
];
  • 因为页面是 404, 所以我们需要修改一下 HTTP 的状态码
if (context.NotFound) {
  res.status(404);
}
res.send(html);
  • 其实这个还是比较简单的,没有什么复杂的地方,就是在 NotFound 组件里定义一个 NotFound 的属性,在服务端校验,然后对应做处理就可以了
  • 5xx 页面和 404 页面是一样的,服务端 catch 到错误,就返回 500 错误,同时渲染 500 的页面

2. 重定向页面

  • 假如我们有一个需要登录才能查看的页面,但是用户没有登录,所以他不能查看,但是我们要把页面重定向到登录页面,让用户进行登录,所以我们需要进行重定向
  • 假如我们现在在进入 /news 页面的时候,需要用户重定向到 / 页面,我们可以在 News 组件里这么操作
import React, { Component } from 'react';
import {Redirect } from 'react-router-dom';

class News extends Component {
  render() {
    return (
      <Redirect to="/" />
    );
  }
}

export default News;
  • 纯粹的客户端渲染,我们也是这个做的,直接使用 Redirect 组件,传递 to 属性就可以了
  • 此时我们在服务端查看 context 的值,就可以查看到一些新的属性
{ csses: [],
  action: 'REPLACE',
  location: {
    pathname: '/',
    search: '',
    hash: '',
    state: undefined
  },
  url: '/'
}
  • 这里有一个 action 的属性,值是 REPLACE,这个是 react-router-dom 帮我们做的,当页面使用 Redirect 组件进行重定向的时候,context 里会添加 action, location 和 url 属性
  • 所以,我们可以使用这些属性在服务端做对应的操作,这里的 redirect 的 url 要使用 context 里的属性,因为可能会有多个重定向组件,我们不知道要重定向到哪里
  • 其实这个也比较简单,没有什么难度
if (context.action === 'REPLACE') {
  res.redirect(301, context.url);
}
res.send(html);
  • 404和重定向写在一起
if (context.action === 'REPLACE') {
  res.redirect(301, context.url);
} else if (context.notFound) {
  res.statusCode = 404;
}
res.send(html);
相关阅读

karuru
329 声望64 粉丝