I am using react-router-dom
and I am guessing that this is causing the problem, but I have no clue where to even start looking or how to fix it. I also am getting errors like Warning: Did not expect server HTML to contain a <nav> in <div>
.
As I stated, I'm not really sure where to look so if you think there is certain code that would be helpful please let me know and I will post it. Otherwise, I can post my code that I use to do SSR.
EDIT : Exact error: Warning: Prop
href did not match. Server: "/profile/5a073dc44cb45b00125e5c82" Client: "profile/5a073dc44cb45b00125e5c82"
did not match. Server: "/profile/5a073dc44cb45b00125e5c82" Client: "profile/5a073dc44cb45b00125e5c82"
I have checked the client and it has /profile/:id
so not sure where it says there is not a /
, as for the other error with the <nav>
in <div>
, I have a nav
inside my header , but I'm not really sure how to go about "fixing" that.
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;
Did you fix this already? I had the similar problem with my react app and fixed it. Here was my problem:
<Link to="./shop">Shop</Link>
my fix:
<Link to="/shop">Shop</Link>
Whatever you are rendering with the server is the issue. I suggest to comb through your routes module and see if you forgot a forward slash somewhere. If that doesn't work look at through the components your importing in the routes file.
To add to Kevorkian answer:
Make sure to prefix all the routes with a /
Note the /update
<Link href={{ pathname: '/update', query: { id: product.id } }}>
This happened to me in nextjs. It was because i had something like Link= /auth/${isLogin?"sign-up":"login"}
. This was an issue because there is no reference at compile time. The should have been isLogin ? "/auth/sign-up" : "/auth/login"}
isLogin ? "/auth/sign-up" : "/auth/login"}
This happened to me in a React/Next project because of next links.
This is the component
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>
);
};
Here we have Link href="#" (This is the server side)
<li class="breadcrumb-item">
<a href="/search?searchTerm=a00&codeSets=1%2C2%2C3%2C4%2C5%2C6%2C7#">Home
</a>
</li>
After the page loaded, it becomes something like that above (This is the client side)
So we have a mismatch here in the DOM and we get this warning
SOLUTION
I was rendering this component on my pages and getting this warning. As a solution, i have implemented dynamic content approach checking some state values before rendering the element.
For instance in my code detail page, I have done that like below.
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>
);
};
I just want to chip in that with Next's Link
component it will accept an empty string for an href
property like it does in native HTML. If you really want a link that links to nowhere you HAVE to use #
. That's how I got my error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.