使用webpack编译我的包(有一个单独的vendor.js,然后是app.js,vendor.js只需要一些基础知识,比如反应等)。我想知道为什么当我在路由器声明中使用{... renderProps}格式时,它会抛出此错误。如果我将{... renderProps}更改为标准routes = {routes}格式,它似乎可以工作,但每个人都倾向于使用{... renderProps},并且我试图找出它为什么&# 39;为我工作。我相信点别名{... x}是一个0阶段的特性,所以我在我的webpack预设中定义了stage-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负责显示错误。
任何人都知道为什么?
答案 0 :(得分:1)
将match
中的app.js
从<Router>
更改为<RouterContext>
并删除历史记录是否会修复它?
match({ routes, location }, (error, redirectLocation, renderProps) => {
render(
<RouterContext
{...renderProps}
/>,
document.getElementById('react-app')
);
})
中建议的内容
答案 1 :(得分:0)
这是因为Router
组件不会将routes
作为道具。
由于这是针对服务器端呈现的,因此代码需要使用RouterContext
而不是Router
。
match
和Router
已被删除,以简化生活,并被MemoryRouter
,BrowserRouter
和ServerRouter
取代。
/* 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
答案 2 :(得分:0)
啊,好的 - 混淆是使用reactRouter.match
和RouterContext
这两个我认为仅用于服务器端渲染。
你应该有一个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'));