【问题标题】:React.js client route match giving "Invalid prop `routes` supplied to `Router`."React.js 客户端路由匹配给出“提供给 `Router` 的无效 prop `routes`。”
【发布时间】:2017-01-23 02:51:38
【问题描述】:

用 webpack 编译我的包(有一个单独的 vendor.js,然后是一个 app.js,vendor.js 只需要一些基础知识,比如 react 等)。我想知道为什么当我在 Router 声明中使用 {...renderProps} 格式时,它会引发此错误。如果我将 {...renderProps} 更改为标准 routes={routes} 格式,它似乎可以工作,但每个人都倾向于使用 {...renderProps},我试图找出它为什么不起作用为了我。我相信点别名 {...x} 是一个阶段 0 功能,所以我在我的 webpack 预设中定义了阶段 0,但似乎不会影响结果。这是我的文件:

app.js:

import React from 'react';
import { render } from 'react-dom';
import { match, Router, RouterContext, browserHistory } from 'react-router'
import { createHistory } from 'history'
import routes from './components/routes/AppRoute.jsx';

const { pathname, search, hash } = window.location;
const location = pathname;

match({ routes, location }, (error, redirectLocation, renderProps) => {
   render(
        <Router 
            {...renderProps} 
            history={browserHistory} 
        />, 
        document.getElementById('react-app')
    );
})

/components/routes/AppRoute.jsx 是:

import AppShell from '../AppShell.jsx';
import Index from '../Index.jsx';

if(typeof require.ensure !== "function") require.ensure = function(d, c) { c(require) }

module.exports = {
  path: '/',
  component: AppShell,
  indexRoute: Index,
  childRoutes: [
    { path: 'test', 
        getComponent(location, cb) {
            require.ensure([], (require) => {
              cb(null, require('../Test.jsx'))
            })
          }
    },
    { path: 'user', 
        getComponent(location, cb) {
            require.ensure([], (require) => {
              cb(null, require('../User.jsx'))
            })
          }
    },
    { path: '*', 
        getComponent(location, cb) {
            require.ensure([], (require) => {
              cb(null, require('../NotFound.jsx'))
            })
          }
    },
    { path: 'app-shell', component: AppShell }
  ] 
}

这似乎已正确导出并正确导入到 app.js 中,因为 console.log 显示了预期的对象。

但由于某些原因在页面加载时,浏览器给出:

dll.vendor.js:330 Warning: Failed prop type: Invalid prop `routes` supplied to `Router`.
    in Router

这个错误是从 dll.vendor.js 文件(不是 app.js)中显示出来的,但我不确定这是否重要,因为我的 react 已加载到供应商文件中,并且 react 负责显示错误。

有人知道为什么吗?

【问题讨论】:

    标签: reactjs webpack react-router


    【解决方案1】:

    app.js 中的match&lt;Router&gt; 更改为&lt;RouterContext&gt; 并删除历史道具是否可以解决问题?

    match({ routes, location }, (error, redirectLocation, renderProps) => {
       render(
            <RouterContext 
                {...renderProps} 
            />, 
            document.getElementById('react-app')
        );
    })
    

    这就是react-router's docs推荐的内容

    【讨论】:

    • 是的,工作。我不知道,我之前有常规的 工作,但是我改变了很多 webpack 的东西,出于某种原因它现在抱怨了。但是,切换到 RouterContext 有效。谢谢大佬!
    • 啊,刚刚注意到一个错误......看起来如果我使用 ,我的链接都不起作用!任何 组件都不会去任何地方,url 不会改变,没有错误。如果我将其更改为 那么一切正常......奇怪
    • 啊,请参阅@uni_nake 的回答。您正在使用服务器端渲染解决方案,我没有注意到您只是在尝试路由客户端。
    【解决方案2】:

    反应路由器 2

    这是因为Router 组件没有将routes 作为prop。

    由于这是服务端渲染,代码需要使用RouterContext而不是Router

    反应路由器 4

    matchRouter 已被删除以简化生活,并已替换为 MemoryRouterBrowserRouterServerRouter

    /* eslint-disable no-param-reassign */
    import React from 'react';
    import { renderToString } from 'react-dom/server';
    import { ServerRouter/* , createServerRenderContext */ } from 'react-router';
    // todo : remove line when this PR is live
    // https://github.com/ReactTraining/react-router/pull/3820
    import createServerRenderContext from 'react-router/createServerRenderContext';
    import { makeRoutes } from '../../app/routes';
    
    const createMarkup = (req, context) => renderToString(
      <ServerRouter location={req.url} context={context} >
        {makeRoutes()}
      </ServerRouter>
    );
    
    const setRouterContext = (req, res, next) => {
      const context = createServerRenderContext();
      const markup = createMarkup(req, context);
      const result = context.getResult();
      if (result.redirect) {
        res.redirect(301, result.redirect.pathname + result.redirect.search);
      } else {
        res.status(result.missed ? 404 : 200);
        res.routerContext = (result.missed) ? createMarkup(req, context) : markup;
        next();
      }
    };
    
    export default setRouterContext;
    

    如需工作演示,请查看react-lego

    【讨论】:

    • 这不适用于服务器端渲染。我有这个工作,但是在使用 webpack 及时渲染和重新启动服务器之间有很多复杂性,我现在只想简化它。不过还是谢谢。
    • 啊,好吧 - 我认为 reactRouter.match 的使用令人困惑,我认为它仅用于服务器端渲染。
    • 真的吗?我读过在客户端使用 match() 在某些情况下有助于解决一些问题......
    • 好吧,我认为这是可以的:github.com/ReactTraining/react-router/blob/master/docs/guides/… 但我不需要它,因为数据基于组件而不是路由。即你可以有一个需要异步数据的组件。这意味着永远不会有异步路由。
    【解决方案3】:

    啊,好吧 - 混淆是围绕reactRouter.matchRouterContext 的使用,我认为这两者都仅用于服务器端渲染。

    你应该有一个Router,它需要孩子和历史(浏览器或内存)。

    ReactDOM.render(
        <Router history={history} >
            <Route path="/" component={ MainLayout }>
              <IndexRoute { ...indexRoute(routes.homepage) } />
              <Route { ...routes.game } />
              <Route { ...routes.notFound } />
            </Route>
        </Router>,
    document.getElementById('html'));
    

    【讨论】:

    • 但是我的路由是在外部定义的,所以我必须使用routes={routes},但我最初的问题是试图确定如何使用{...renderProps}。我猜客户端只需要使用路由和历史定义为单独属性的路由器?
    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 2016-08-19
    • 2020-08-01
    相关资源
    最近更新 更多