警告:属性`href`不匹配。使用React服务器端渲染。

21

我正在使用react-router-dom,我猜这可能是问题的原因,但我不知道从哪里开始查找或如何解决它。我也收到了像Warning: Did not expect server HTML to contain a <nav> in <div>这样的错误。

正如我所说,我不确定应该在哪里查找,所以如果您认为某些代码会有帮助,请告诉我,我会发布它。否则,我可以发布用于SSR的代码。

编辑: 精确的错误:Warning: Prophrefdid not match. Server: "/profile/5a073dc44cb45b00125e5c82" Client: "profile/5a073dc44cb45b00125e5c82"

我已经检查过客户端,它有/profile/:id,所以不知道为什么会显示没有/,至于其他关于在<div>中包含<nav>的错误,我在我的头部中有一个nav,但我真的不确定该如何“修复”它。

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;
5个回答

28

你已经修复了这个问题吗?我曾经遇到过我的React应用程序类似的问题,并解决了它。这是我的问题:

<Link to="./shop">商店</Link>

我的解决办法:

<Link to="/shop">商店</Link>

无论您在服务器上呈现什么,都是问题所在。我建议逐个查看您的路由模块,并查看是否忘记了某个正斜杠。如果这样做不起作用,请查看路由文件中导入的组件。


13

补充 Kevorkian 的回答:

确保所有路由都以 / 为前缀

注意 /update

<Link href={{ pathname: '/update', query: { id: product.id } }}>

2

这件事情发生在我的Next.js项目中。问题出在我使用了像/auth/${isLogin?"sign-up":"login"}>这样的代码。由于没有编译时的引用,所以导致了问题。正确的写法应该是isLogin ? "/auth/sign-up" : "/auth/login"


0
这在我的React/Next项目中发生了,因为有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&amp;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>
    );
};

0

我只是想说,使用 Next 的 Link 组件时,它不会像原生 HTML 那样接受空字符串作为 href 属性。如果你真的想要一个指向无处的链接,你必须使用 #。这就是我犯错误的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接