警告 Prop `href` 不匹配。使用 React 服务器端渲染
Warning Prop `href` did not match. using react server-side-rendering
我正在使用 react-router-dom
,我猜这是导致问题的原因,但我不知道从哪里开始寻找或如何解决它。我也收到类似 Warning: Did not expect server HTML to contain a <nav> in <div>
.
的错误
正如我所说,我不太确定去哪里寻找,所以如果您认为有某些代码会有所帮助,请告诉我,我会 post 它。否则,我可以 post 我用来做 SSR 的代码。
编辑:确切错误:Warning: Prop
hrefdid not match. Server: "/profile/5a073dc44cb45b00125e5c82" Client: "profile/5a073dc44cb45b00125e5c82"
我检查了客户端,它有 /profile/:id
,所以不确定它在哪里说没有 /
,至于 <nav>
in [=18] 的另一个错误=] ,我的 header 里面有一个 nav
,但我不太确定如何处理 "fixing" 那个。
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import serialize from 'serialize-javascript';
import { Helmet } from 'react-helmet';
import { matchRoutes } from 'react-router-config';
import routes from './src/routes';
import createStore from './src/stores';
function handleRender(req, res) {
let initial = {};
if (req.vertexSession != null && req.vertexSession.user != null) {
initial.user = { currentUser: req.vertexSession.user };
}
const store = createStore.configure(initial); // create Store in order to get data from redux
const promises = matchRoutes(routes, req.path)
.map(({ route, match }) => {
// Matches the route and loads data if loadData function is there
return route.loadData
? route.loadData(store)
: route.loadDataWithMatch ? route.loadDataWithMatch(store, match) : null;
})
.map(promise => {
if (promise) {
return new Promise((resolve, reject) => {
promise.then(resolve).catch(resolve); // lets all data load even if route fails
});
}
});
Promise.all(promises).then(() => {
const context = {};
if (context.url) {
return res.redirect(301, context.url); // redirect for non auth users
}
if (context.notFound) {
res.status(404); // set status to 404 for unknown route
}
const content = renderToString(
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
<div>{renderRoutes(routes)}</div>
</StaticRouter>
</Provider>
);
// console.log(store.getState());
const initialState = serialize(store.getState());
const helmet = Helmet.renderStatic();
res.render('index', { content, initialState, helmet });
});
}
module.exports = handleRender;
你已经解决这个问题了吗?我的反应应用程序遇到了类似的问题并修复了它。这是我的问题:
<Link to="./shop">Shop</Link>
我的修复:
<Link to="/shop">Shop</Link>
无论您使用服务器渲染什么,都是问题所在。我建议梳理一下你的路线模块,看看你是否忘记了某处的正斜杠。如果这不起作用,请查看您在路由文件中导入的组件。
添加到答案:
确保在所有路由前加上 /
注意 /更新
<Link href={{ pathname: '/update', query: { id: product.id } }}>
这发生在我的 nextjs 中。那是因为我有类似的东西
Link=/auth/${isLogin?"sign-up":"login"}
。这是一个问题,因为在编译时没有引用。应该是 isLogin ? "/auth/sign-up" : "/auth/login"}
由于下一个链接,我在 React/Next 项目中发生了这种情况。
这是组件
const Breadcrumb = (props) => {
return (
<Row>
<Col xs="12">
<div className="page-title-box d-sm-flex align-items-center justify-content-between">
<h4 className="mb-0 font-size-18">{props.breadcrumbItem}</h4>
<div className="page-title-right">
<ol className="breadcrumb m-0">
<BreadcrumbItem>
<Link href="#">{props.title}</Link>
</BreadcrumbItem>
<BreadcrumbItem active>
<Link href="#">{props.breadcrumbItem}</Link>
</BreadcrumbItem>
</ol>
</div>
</div>
</Col>
</Row>
);
};
这里有Link href="#"(这是服务器端)
<li class="breadcrumb-item">
<a href="/search?searchTerm=a00&codeSets=1%2C2%2C3%2C4%2C5%2C6%2C7#">Home
</a>
</li>
页面加载完成后变成如上图(这是客户端)
所以我们在 DOM 中有一个不匹配,我们得到这个警告
解决方案
我在我的页面上呈现此组件并收到此警告。作为解决方案,我实现了动态内容方法,在呈现元素之前检查一些状态值。
例如在我的代码详细信息页面中,我是这样做的,如下所示。
const CodeDetail = (props) => {
const [code, setCode] = useState<any>(null);
useEffect(() => {
if (props.router.query.code) {
if (codesData.filter(codeData => codeData.code == props.router.query.code).length > 0) {
setCode(codesData.find(codeData => codeData.code == props.router.query.code));
}
else {
setCode({});
}
}
}, [props.router]);
let pageContent;
if (code !== null) {
pageContent = (<Container fluid={true}><Breadcrumbs title="Codes" breadcrumbItem="Code Detail" /></Container>)
}
else {
pageContent = null;
}
return(
<React.Fragment>{pageContent}</React.Fragment>
);
};
我正在使用 react-router-dom
,我猜这是导致问题的原因,但我不知道从哪里开始寻找或如何解决它。我也收到类似 Warning: Did not expect server HTML to contain a <nav> in <div>
.
正如我所说,我不太确定去哪里寻找,所以如果您认为有某些代码会有所帮助,请告诉我,我会 post 它。否则,我可以 post 我用来做 SSR 的代码。
编辑:确切错误:Warning: Prop
hrefdid not match. Server: "/profile/5a073dc44cb45b00125e5c82" Client: "profile/5a073dc44cb45b00125e5c82"
我检查了客户端,它有 /profile/:id
,所以不确定它在哪里说没有 /
,至于 <nav>
in [=18] 的另一个错误=] ,我的 header 里面有一个 nav
,但我不太确定如何处理 "fixing" 那个。
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import serialize from 'serialize-javascript';
import { Helmet } from 'react-helmet';
import { matchRoutes } from 'react-router-config';
import routes from './src/routes';
import createStore from './src/stores';
function handleRender(req, res) {
let initial = {};
if (req.vertexSession != null && req.vertexSession.user != null) {
initial.user = { currentUser: req.vertexSession.user };
}
const store = createStore.configure(initial); // create Store in order to get data from redux
const promises = matchRoutes(routes, req.path)
.map(({ route, match }) => {
// Matches the route and loads data if loadData function is there
return route.loadData
? route.loadData(store)
: route.loadDataWithMatch ? route.loadDataWithMatch(store, match) : null;
})
.map(promise => {
if (promise) {
return new Promise((resolve, reject) => {
promise.then(resolve).catch(resolve); // lets all data load even if route fails
});
}
});
Promise.all(promises).then(() => {
const context = {};
if (context.url) {
return res.redirect(301, context.url); // redirect for non auth users
}
if (context.notFound) {
res.status(404); // set status to 404 for unknown route
}
const content = renderToString(
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
<div>{renderRoutes(routes)}</div>
</StaticRouter>
</Provider>
);
// console.log(store.getState());
const initialState = serialize(store.getState());
const helmet = Helmet.renderStatic();
res.render('index', { content, initialState, helmet });
});
}
module.exports = handleRender;
你已经解决这个问题了吗?我的反应应用程序遇到了类似的问题并修复了它。这是我的问题:
<Link to="./shop">Shop</Link>
我的修复:
<Link to="/shop">Shop</Link>
无论您使用服务器渲染什么,都是问题所在。我建议梳理一下你的路线模块,看看你是否忘记了某处的正斜杠。如果这不起作用,请查看您在路由文件中导入的组件。
添加到
确保在所有路由前加上 /
注意 /更新
<Link href={{ pathname: '/update', query: { id: product.id } }}>
这发生在我的 nextjs 中。那是因为我有类似的东西
Link=/auth/${isLogin?"sign-up":"login"}
。这是一个问题,因为在编译时没有引用。应该是 isLogin ? "/auth/sign-up" : "/auth/login"}
由于下一个链接,我在 React/Next 项目中发生了这种情况。
这是组件
const Breadcrumb = (props) => {
return (
<Row>
<Col xs="12">
<div className="page-title-box d-sm-flex align-items-center justify-content-between">
<h4 className="mb-0 font-size-18">{props.breadcrumbItem}</h4>
<div className="page-title-right">
<ol className="breadcrumb m-0">
<BreadcrumbItem>
<Link href="#">{props.title}</Link>
</BreadcrumbItem>
<BreadcrumbItem active>
<Link href="#">{props.breadcrumbItem}</Link>
</BreadcrumbItem>
</ol>
</div>
</div>
</Col>
</Row>
);
};
这里有Link href="#"(这是服务器端)
<li class="breadcrumb-item">
<a href="/search?searchTerm=a00&codeSets=1%2C2%2C3%2C4%2C5%2C6%2C7#">Home
</a>
</li>
页面加载完成后变成如上图(这是客户端)
所以我们在 DOM 中有一个不匹配,我们得到这个警告
解决方案
我在我的页面上呈现此组件并收到此警告。作为解决方案,我实现了动态内容方法,在呈现元素之前检查一些状态值。
例如在我的代码详细信息页面中,我是这样做的,如下所示。
const CodeDetail = (props) => {
const [code, setCode] = useState<any>(null);
useEffect(() => {
if (props.router.query.code) {
if (codesData.filter(codeData => codeData.code == props.router.query.code).length > 0) {
setCode(codesData.find(codeData => codeData.code == props.router.query.code));
}
else {
setCode({});
}
}
}, [props.router]);
let pageContent;
if (code !== null) {
pageContent = (<Container fluid={true}><Breadcrumbs title="Codes" breadcrumbItem="Code Detail" /></Container>)
}
else {
pageContent = null;
}
return(
<React.Fragment>{pageContent}</React.Fragment>
);
};