动态路径段OR 404

时间:2016-01-15 11:29:51

标签: react-router

我有一个应用程序需要在呈现404之前使用后端API进行检查。路由流程的工作原理如下:

请求进入/ {INCOMING_PATH},应用程序尝试从api.com/pages/{INCOMING_PATH获取和呈现数据。

如果API返回404,则应用应返回404.如果不是,则呈现数据。

我不会因此用例而被出售。 {INCOMING_PATH}将是动态的,可能在路径中使用斜杠和扩展名。这是否可以在React Router中实现(具有适当的SSR行为)?如果是这样,我该怎么办?

This question was originally posted on github是另一位用户。他们被要求在这里发布,因为这是一个支持请求。但它似乎没有。我现在陷入了完全相同的问题。)

2 个答案:

答案 0 :(得分:1)

我已使用React Nested Status模块解决了这个问题。

我正在使用https://github.com/erikras/react-redux-universal-hot-example,因此此代码适用于此。有关更通用的解决方案,请参阅React Nested Status

编辑到server.js:

在顶部

import NestedStatus from 'react-nested-status';

在底部替换:

const status = getStatusFromRoutes(routerState.routes);
if (status) {
  res.status(status);
}
res.send('<!doctype html>\n' +
  ReactDOM.renderToString(<Html assets={webpackIsomorphicTools.assets()} component={component} store={store}/>));

使用:

const repsonse = ReactDOM.renderToString(
  <Html assets={webpackIsomorphicTools.assets()} component={component} store={store}/>
);

const status = getStatusFromRoutes(routerState.routes);
if (status) {
  res.status(status);
}

const nestedStatus = NestedStatus.rewind();
if (nestedStatus !== 200) {
  res.status(nestedStatus);
}

res.send('<!doctype html>\n' + repsonse);

然后,您需要为404服务的容器/组件:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import connectData from 'helpers/connectData';
import { fetchApiData } from 'redux/modules/foo/fetchApiData';
import { NotFound } from 'containers';

@connectData(null, (getReduxState, dispatch, state, params) => {
  return dispatch(fetchApiData(params.fooId));
})
@connect(
  (reduxState) => ({
    fooData: reduxState.foo.data,
  })
)
export default class ProductType extends Component {
  static propTypes = {
    fooData: PropTypes.object,
  }

  render() {
    let content;
    // ... whatever your api sends back to indicate this is a 404
    if (!this.props.fooData.exists) {
      content = <NotFound/>;
    } else {
      content = (
        <div className={styles.productType}>
          Normal content...
        </div>
      );
    }
    return content;
  }
}

最后替换/src/containers/NotFound/NotFound.js

import React, { Component } from 'react';
import NestedStatus from 'react-nested-status';

export default class NotFound extends Component {

  render() {
    return (
      <NestedStatus code={404}>
        <div className="container">
          <h1>Error 404! Page not found.</h1>
        </div>
      </NestedStatus>
    );
  }
}

答案 1 :(得分:-1)

我不确定您使用的是哪种状态实施。但是,如果你使用redux,那么我认为最简单的方法是使用redux-simple-router。有了它,您的路由将在您的州内同步,因此您可以派遣动作创建者来更改路由器路径。我会尝试使用动作创建器更新satate,而不是直接从组件中推送状态。真相点必须始终是状态,在你的情况下我会按如下方式行事:

需要获取数据的组件将订阅&#34; dataReducer&#34;这是该组件应该关注的孤立状态部分。也许dataReducer的初始状态是一个空数组。然后,在componentWillMount中,您可以调度以下操作:dispatch(fetchDataFromApi))如果响应代码为404,那么在操作fetchDataFromApi中您可以调度另一个操作,这只是一个像这样的对象:

{type:SET_NOT_FOUND_ERROR}

该操作将由reducer dataReducer处理,并将返回一个带有对象的新状态(考虑Immutability),该对象将出现属性错误,该错误将是一个包含原因的字符串,或者您想要的任何内容

然后,在componentWillReceiveProps方法中,您可以检查nextProps是否有错误。如果出现错误,您可以呈现错误组件,甚至可以调度操作以转到react-router处理的错误页面。

如果没有错误,那么你可以调度一个动作(感谢redux-simple-router)去路径y