简体   繁体   English

警告:没想到服务器 HTML 包含<li>在<ul> . 在 React/Redux 服务器端渲染

[英]Warning: Did not expect server HTML to contain a <li> in <ul>. in React/Redux Server side Rendering

I am doing Server Side Rendering for the first time with React and Redux and seeming to be having a little difficulty.我第一次使用 React 和 Redux 进行服务器端渲染,似乎有点困难。 I am getting the warning:我收到警告:

Warning: Did not expect server HTML to contain a <li> in <ul>.

I have looked this up and it means that there is a html tree mismatch.我查了一下,这意味着 html 树不匹配。 I am not sure how that is.我不确定那是怎么回事。 Is there an obvious way to fix it?有没有明显的方法来解决它? Here is the code I have that is throwing the warning.这是我抛出警告的代码。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import actions from '../actions';

class UsersList extends Component {
  componentDidMount() {
    if (this.props.users.length > 0) {
      return;
    }
    this.props.fetchUsers();
  }

  render() {
    const { users } = this.props;
    return (
      <div>
        <ul>
          {users.map(user => {
            return <li key={user.id}>{user.name}</li>;
          })}
        </ul>
      </div>
    );
  }
}

const stateToProps = state => {
  return {
    users: state.users
  };
};

const dispatchToProps = dispatch => {
  return {
    fetchUsers: () => dispatch(actions.fetchUsers())
  };
};

const loadData = store => {
  return store.dispatch(actions.fetchUsers());
};

export { loadData };
export default connect(stateToProps, dispatchToProps)(UsersList);

Here is the client.js:这是 client.js:

// Startup point for the client side application
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';

import Routes from './Routes';
import reducers from './reducers';

const store = createStore(reducers, {}, applyMiddleware(thunk));

ReactDOM.hydrate(
  <Provider store={store}>
    <BrowserRouter>
      <div>{renderRoutes(Routes)}</div>
    </BrowserRouter>
  </Provider>,
  document.querySelector('#root')
);

The problem was that since the server had rendered the list of users already, it had a ul with li s.问题是因为服务器已经呈现了用户列表,所以它有一个带有liul But when the client loaded there was no initial data so there was only an ul and no li s to accompany it.但是当客户端加载时没有初始数据,所以只有一个ul而没有li s伴随它。

To fix this problem, which I think not many will have because you need to do this anyway in server side rendering is to pass some initial state into the createStore redux function:要解决这个问题,我认为没有多少人会遇到这个问题,因为无论如何在服务器端渲染中都需要这样做是将一些初始状态传递给createStore redux 函数:

You will need to do this in two places.您需要在两个地方执行此操作。 In the html on your server side and in your entry point on the client side.在服务器端的 html 和客户端的入口点中。

Short example could be:简短的例子可能是:

<html>
  <head></head>
  <body>
    <div id="root">${content}</div>
    <script>
      window.INITIAL_STATE = ${serialize(store.getState())}
    </script>
    <script src="bundle.js"></script>
  </body>
</html>

As you can see we have to set the initial state to the store that you created on your server side.如您所见,我们必须将初始状态设置为您在服务器端创建的商店。

On your client side:在您的客户端:

// Startup point for the client side application
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';

import Routes from './Routes';
import reducers from './reducers';

const store = createStore(reducers, window.INITIAL_STATE, applyMiddleware(thunk));

ReactDOM.hydrate(
  <Provider store={store}>
    <BrowserRouter>
      <div>{renderRoutes(Routes)}</div>
    </BrowserRouter>
  </Provider>,
  document.querySelector('#root')
);

Now you have access to this global variable window.INITIAL_STATE and you just pass that through into the second argument of createStore which is the initial state.现在您可以访问这个全局变量window.INITIAL_STATE并且您只需将它传递给createStore的第二个参数,即初始状态。

I'm posting here now because I was searching this exact issue with nextJS SSG.我现在在这里发帖是因为我正在使用 nextJS SSG 搜索这个确切的问题。 Just like Dave Newton mentioned, in the jsx return I would simply add a check and not render the <ul> if it is empty due to a conditional check on the <li> 's.就像 Dave Newton 提到的那样,在 jsx 返回中,我会简单地添加一个检查,如果<ul>由于对<li>的条件检查而为空,则不会渲染它。 Something like this:像这样的东西:

           {Object.keys(el[i]).length > 0 ? 
              <ul>
                {getKeys(docs, item, el).map(
                  ([key, value], i) => {
                    const name = `${docs[item][el][key].name}`
                    const path = `${docs[item][el][key].path}`
                    return (name !== "undefined") && (
                    <li key={i}><a href={path}>{name}</a></li>
                  )}
                )}
              </ul>
              : ''
            } 

React 17 警告:没想到服务器 HTML 包含一个<a>in</a><div></div><div id="text_translate"><p> 我已经通读了现有的解决方案,但似乎仍然无法让它发挥作用。</p><p> 组件/NavBar.tsx</p><pre> import { Box, Link } from "@chakra-ui/react"; import { FunctionComponent } from "react"; import NextLink from "next/link"; interface NavBarProps {} const NavBar: FunctionComponent<any> = (props) => { return ( <Box {...props} bg="tomato" w="100%" p={4} ml={"auto"} color="white"> <NextLink href="/login"> <Link mr={4}>Login</Link> </NextLink> <NextLink href="/register"> <Link>Register</Link> </NextLink> </Box> ); }; export default NavBar;</pre><p> 索引.tsx</p><pre> import NavBar from "../components/navbar"; const Index = () => ( <> <NavBar></NavBar> <div>hello world</div> </> ); export default Index;</pre><p> 错误截图<a href="https://i.stack.imgur.com/cB1j7.png" rel="nofollow noreferrer">错误信息</a></p></div> - React 17 Warning: Did not expect server HTML to contain a <a> in <div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React 17 警告:没想到服务器 HTML 包含一个<a>in</a><div></div><div id="text_translate"><p> 我已经通读了现有的解决方案,但似乎仍然无法让它发挥作用。</p><p> 组件/NavBar.tsx</p><pre> import { Box, Link } from "@chakra-ui/react"; import { FunctionComponent } from "react"; import NextLink from "next/link"; interface NavBarProps {} const NavBar: FunctionComponent<any> = (props) => { return ( <Box {...props} bg="tomato" w="100%" p={4} ml={"auto"} color="white"> <NextLink href="/login"> <Link mr={4}>Login</Link> </NextLink> <NextLink href="/register"> <Link>Register</Link> </NextLink> </Box> ); }; export default NavBar;</pre><p> 索引.tsx</p><pre> import NavBar from "../components/navbar"; const Index = () => ( <> <NavBar></NavBar> <div>hello world</div> </> ); export default Index;</pre><p> 错误截图<a href="https://i.stack.imgur.com/cB1j7.png" rel="nofollow noreferrer">错误信息</a></p></div> - React 17 Warning: Did not expect server HTML to contain a <a> in <div> 不要指望服务器HTML在<main>中包含<div> - Did not expect server HTML to contain a <div> in <main> 使用redux-saga反应服务器端渲染 - React server side rendering with redux-saga 警告 Prop `href` 不匹配。 使用反应服务器端渲染 - Warning Prop `href` did not match. using react server-side-rendering 使用redux进行服务器端渲染 - Server side rendering with redux Rails 5 Redux React Server Side Rendering向客户端JavaScript警告“用新的…替换React渲染的子级…” - Rails 5 Redux React Server Side Rendering gives client side JavaScript warning 'Replacing React-rendered children with a new…' 使用 redux 和 react 的异步服务器端渲染 - Async server-side rendering using redux & react 执行反应redux服务器端渲染时出现“意外的令牌&lt;” - “Unexpected token < ” when doing react redux server side rendering 如何在React / redux中进行服务器端渲染? - How to do server-side rendering in React/redux? 使用Express进行React Server端渲染-客户端校验和样式警告 - React Server side rendering with Express - warning on the client checksum & Styling
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM