Bob*_*aev 16 typescript reactjs material-ui server-side-rendering next.js
我正在使用 nextjs 和 mui。我在渲染页面时遇到警告。这是我的代码。请帮忙解决问题!!!
\nimport "../styles/globals.scss";\nimport { AppProps } from "next/app";\nimport useGetAuthentication from "../hooks/useGetAuthentication";\nimport States from "../interfaces/states";\nimport STATUS from "../constants/status";\nimport { CssBaseline } from "@mui/material";\nimport { ThemeProvider } from "@mui/material/styles";\nimport theme from "../styles/theme";\nimport Layout from "../layouts/Layout";\nimport Head from "next/head";\nimport * as React from "react";\nimport Login from "../components/Login";\nimport { Box } from "@mui/material";\n\ninterface MyAppProps extends AppProps {\n emotionCache?: EmotionCache;\n}\n\nconst checkStatusCode = (statusCode: number): boolean => {\n return statusCode === STATUS.NOT_FOUND || statusCode === STATUS.INTERNAL_SERVER_ERROR;\n};\n\nfunction App({ Component, pageProps }: AppProps) {\n const { states } = pageProps;\n const { statusCode } = pageProps;\n const { isAuthorized } = useGetAuthentication(states as States);\n\n console.log("App -> Component", Component);\n console.log("App -> pageProps", pageProps);\n console.log("App -> states", states);\n console.log("App -> statusCode", statusCode);\n const drawerWidth: number = 240;\n if (!checkStatusCode(statusCode) && !isAuthorized)\n return (\n <Box\n component="main"\n sx={{\n flexGrow: 1,\n p: 3,\n width: { lg: "230px", sm: `calc(100% - ${drawerWidth}px)` }\n }}\n >\n <Login />\n </Box>\n );\n\n return (\n <>\n <Head>\n <meta name="viewport" content="initial-scale=1, width=device-width" />\n </Head>\n <ThemeProvider theme={theme}>\n <CssBaseline />\n <Layout>\n <Component {...pageProps} />\n </Layout>\n </ThemeProvider>\n </>\n );\n}\n\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n登录组件如下
\n import React, { useEffect } from "react";\nimport authenticationStore from "../../stores/persistences/authenticationStore";\nimport TestHttp from "../../httpModules/testHttp";\nimport STATUS from "../../constants/status";\nimport RequestSignIn from "../../interfaces/test/requestSignIn";\nimport styles from "./login.module.scss";\nimport { Alert, FormControlLabel, Grid, Paper, TextField, Typography, Stack, Button, Checkbox } from "@mui/material";\nimport Image from "next/image";\nimport useLoginInputs from "../../hooks/useLoginInputs";\nimport LocalStorageHandler from "../../utils/localStorageHandler";\nimport RememberId from "../../interfaces/rememberId";\nimport ERROR_MESSAGE from "../../constants/errorMessage";\nimport LOGIN_INFO from "../../constants/loginInfo";\n\nconst Login: React.FC = () => {\n const localStorageHandler = new LocalStorageHandler<RememberId>();\n const authorize = authenticationStore((state) => state.authorize);\n const testHttp = new TestHttp();\n const { inputs, setInputs, isRememberChecked, isError, setIsError, isIdEmpty, setIsIdEmpty, isPasswordEmpty, setIsPasswordEmpty, inputsHandler, checkboxHandler } = useLoginInputs([\n "id",\n "password"\n ]);\n\n const { id, password } = inputs;\n\n const onLoginHandler = async (): Promise<void> => {\n if (isIdEmpty) {\n return setIsError(ERROR_MESSAGE.ID_EMPTY);\n }\n if (isPasswordEmpty) {\n return setIsError(ERROR_MESSAGE.PASSWORD_EMPTY);\n }\n const signInInfo: RequestSignIn = { id, password };\n const { statusCode, jsonResult } = await testHttp.signIn(false, signInInfo);\n\n /*\n * \xec\x9d\xb8\xec\xa6\x9d \xec\x8b\xa4\xed\x8c\xa8 (\xec\x95\x84\xec\x9d\xb4\xeb\x94\x94, \xeb\xb9\x84\xeb\xb0\x80\xeb\xb2\x88\xed\x98\xb8 \xec\x9d\xbc\xec\xb9\x98 \xed\x95\x98\xec\xa7\x80 \xec\x95\x8a\xeb\x8a\x94 \xea\xb2\xbd\xec\x9a\xb0 \xeb\x93\xb1) \xeb\xb0\x9c\xec\x83\x9d \xec\x8b\x9c \xec\xbd\x94\xeb\x93\x9c \xec\x9e\x91\xec\x84\xb1\n */\n\n if (statusCode !== STATUS.OK) {\n setIsError(true);\n return;\n }\n const { userInfo, tokenInfo } = jsonResult;\n authorize(statusCode, userInfo, tokenInfo);\n if (!isRememberChecked) return localStorageHandler.removeLocalStorageData(LOGIN_INFO.REMEMBER_ID);\n localStorageHandler.setLocalStorageData("rememberId", {\n id\n });\n };\n\n useEffect(() => {\n console.log("\xed\x95\x98\xec\x9d\xb4");\n setIsIdEmpty(id.length <= 0);\n setIsPasswordEmpty(password.length <= 0);\n setIsError(null);\n }, [id, password]);\n\n console.log("id", id);\n console.log("password", password);\n return (\n <Grid>\n <Paper elevation={10} className={styles.container}>\n <Grid align={"center"}>\n <div className={styles.logo}>\n <Image src={"/images/logo.svg"} width={"200px"} height={"80px"} alt={"logo"} />\n <Typography variant={"h6"}>\xea\xb4\x80\xeb\xa6\xac\xec\x9e\x90</Typography>\n </div>\n </Grid>\n <Stack spacing={1} justifyContent={"center"} alignItems={"center"} className={styles["login-container"]}>\n <TextField name={"id"} placeholder={"\xec\x95\x84\xec\x9d\xb4\xeb\x94\x94\xeb\xa5\xbc \xec\x9e\x85\xeb\xa0\xa5\xed\x95\xb4\xec\xa3\xbc\xec\x84\xb8\xec\x9a\x94."} required value={id} type={"text"} className={styles["login-input"]} onChange={inputsHandler} />\n <TextField name={"password"} placeholder={"\xeb\xb9\x84\xeb\xb0\x80\xeb\xb2\x88\xed\x98\xb8\xeb\xa5\xbc \xec\x9e\x85\xeb\xa0\xa5\xed\x95\x98\xec\x84\xb8\xec\x9a\x94."} required value={password} type={"password"} className={styles["login-input"]} onChange={inputsHandler} />\n </Stack>\n <Stack>\n <FormControlLabel control={<Checkbox checked={isRememberChecked} />} label={"\xec\x95\x84\xec\x9d\xb4\xeb\x94\x94 \xec\xa0\x80\xec\x9e\xa5"} className={styles.checkbox} onChange={checkboxHandler} />\n </Stack>\n <Stack justifyContent={"center"} alignItems={"center"}>\n <Button type={"submit"} color={"primary"} variant={"contained"} className={styles["login-button"]} size={"large"} onClick={onLoginHandler}>\n \xeb\xa1\x9c\xea\xb7\xb8\xec\x9d\xb8\n </Button>\n </Stack>\n <Stack justifyContent={"center"} alignItems={"center"} className={styles["error-message"]}>\n <div>\n {isError && (\n <Alert severity={"error"}>\n <strong>{isError}</strong>\n </Alert>\n )}\n </div>\n </Stack>\n </Paper>\n </Grid>\n );\n};\n\nexport default Login;\n
Run Code Online (Sandbox Code Playgroud)\n警告是
\nWarning: Expected server HTML to contain a matching <div> in <div>.\n at div\n at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js:57:66)\n at Box (webpack-internal:///./node_modules/@mui/system/esm/createBox.js:36:72)\n at Layout (webpack-internal:///./layouts/Layout/index.tsx:16:26)\n at InnerThemeProvider (webpack-internal:///./node_modules/@mui/system/esm/ThemeProvider/ThemeProvider.js:21:70)\n at ThemeProvider (webpack-internal:///./node_modules/@mui/private-theming/ThemeProvider/ThemeProvider.js:47:5)\n at ThemeProvider (webpack-internal:///./node_modules/@mui/system/esm/ThemeProvider/ThemeProvider.js:41:5)\n at App (webpack-internal:///./pages/_app.tsx:61:27)\n at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:20638)\n at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:23179)\n at Container (webpack-internal:///./node_modules/next/dist/client/index.js:323:9)\n at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:820:26)\n at Root (webpack-internal:///./node_modules/next/dist/client/index.js:944:27)\nwindow.console.error @ next-dev.js?3515:25\n
Run Code Online (Sandbox Code Playgroud)\n
bas*_*rat 12
很可能是一个Server<>Client
过时的问题。
您使用的组件在服务器 (SSR) 与客户端 (CSR) 上的渲染方式不同(由于编码错误)。可以通过添加suppressHydrationWarning={true}
有问题的组件来消除这种情况。
我见过的另一个例子是有人设置了dangerouslySetInnerHtml
无效的 HTML。修复方法是更正 HTML 或将其静音,就像我们在情况 2 中所做的那样。
azw*_*bar 12
使用钩子进行的正在进行的值更新也可能导致此问题。为了防止这种情况,只需将变量值从钩子复制到 useEffect 钩子的状态即可。这是例子
import { useAccount } from "wagmi";
...
const { address, isConnected, isConnecting } = useAccount();
// the value of these variable above are changed dynamically
const [connectionStat, setConnectionStat] = useState();
const [addr, setAddr] = useState();
// copy the value to state here
useEffect(() => {
setConnectionStat(isConnected);
setAddr(address);
}, [address, isConnected])
// then now we can display the value properly
return (
<div>
<p>Connection status : {connectionStat}</p>
<p>Connected to : {addr}</p>
....
</div>
);
Run Code Online (Sandbox Code Playgroud)
说明:直接从钩子传递值到 JSX/view 可能会导致 JSX/view 内部的值不一致,因此页面渲染也不一致,并且 SSR 和客户端中的值之间会有不同的值。
希望能帮助到你。
我遇到的真正问题是 LastPass 扩展将该死的 DIV 元素注入到我的代码中。像这样的东西:
<div data-lastpass-icon-root="true" style="position: relative !important; height: 0px !important; width: 0px !important; float: left !important;"></div>
Run Code Online (Sandbox Code Playgroud)
这显然导致服务器和客户端具有不同的节点结构。一旦将 localhost 排除在 LastPass 之外(这并不容易!),错误就消失了。
归档时间: |
|
查看次数: |
42511 次 |
最近记录: |