reactjs - ReactDOMServer.renderToString() - 它到底是做什么的?
问题描述
contructor()
我知道它只是将 HTML 呈现为文本,所以说到类组件,只有render()
在renderToString()
. 但是我注意到一些关于函数组件的奇怪行为。考虑以下组件示例:
function MyComponent() {
console.log(1);
return(
<React.Fragment>
Some text
</React.Fragment>
)
}
我只是console.log()
在函数组件内部使用,我猜它相当于constructor()
类组件内部的方法。
renderToString()
在快速路由处理程序中调用:
import { ServerStyleSheets, ThemeProvider } from '@material-ui/core/styles';
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import theme from 'mui/theme';
import App from 'components/App';
const SERVER_PORT = 8081; // Port for Express to listen
const app = express();
app.get('*', async (req, res) => {
const sheets = new ServerStyleSheets();
const inlineApp = renderToString(
sheets.collect(
<Provider store={exampleStore}>
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
</Provider>,
),
);
const css = sheets.toString();
const renderedHTML = `
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style id="jss">${css}</style>
<title>Repl.it</title>
</head>
<body>
<div id="root">${inlineApp}</div>
<script>
window.STATE = ${JSON.stringify(exampleStore.getState())};
</script>
<script src="app.js"></script>
</body>
</html>
`;
res.send(renderedHTML);
});
app.listen(SERVER_PORT, () => {
console.log(`Listening at http://localhost:${SERVER_PORT}`);
});
问题是我在调用ReactDOMServer.renderToString()
一次时得到了两次控制台输出。我不在服务器端使用双重渲染。所以我有两个问题:
你能解释一下这里到底发生了什么吗?
如果这是一个正确的行为,那么有没有办法在 期间只运行一些代码
renderToString()
?
解决方案
没有足够的数据来做出明确的诊断,但可能是你在 React 的严格模式下运行?
看看这个:https ://reactjs.org/docs/strict-mode.html
严格模式不能自动为您检测副作用,但可以通过使它们更具确定性来帮助您发现它们。这是通过有意双重调用以下函数来完成的:
- 类组件构造函数、render 和 shouldComponentUpdate 方法
- 类组件静态 getDerivedStateFromProps 方法
- 功能组件体
- 状态更新函数(setState 的第一个参数)
- 传递给 useState、useMemo 或 useReducer 的函数
如果不是这种情况......并且我实际上并没有<StrictMode>
在您的代码中看到,那么如果您制作一个最小的可重现示例会很好。
另请注意,虽然函数组件主体在严格模式下调用了两次,console.log()
但从React 17开始的 s被覆盖,因此您应该在控制台上只看到一条记录。但这可以改变。不是每个人都对此感到满意,现在有一个PR至少可以选择退出这种行为。
推荐阅读
- php - 如何克隆 Laravel 项目并在 Mamp 上运行
- scala - 如何将 Kafka Streams 的 Scala API 定义为 build.sbt 中的依赖项?
- php - php从字符串中删除重复项,如果重复长度> 4
- ios - 如何防止 UIButton touchDown 和 touchUpInside 内的竞争条件?
- php - 如果返回成功消息,会话不起作用(代码已更新)
- javascript - Angular 2初始化变量类型属性
- php - 以编程方式更新 Woocommerce 订单上修改的日期
- python - SQLIite 列名有尾括号
- ios - Facebook 登录错误 - 构建 URL 的未知错误(com.facebook.sdk.core 错误 3)
- amazon-web-services - 在 AWS 中授予 Docker 容器 VPC 访问权限