警告 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: Prophrefdid 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&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>
    );
};