我正在我的React/Redux应用程序中第一次尝试服务器端渲染.我现在遇到的一个问题是我需要初始状态来生成一个随机生成的字符串,然后将其作为prop传递给我的主要App组件.这显然是一个问题,因为它为客户端和服务器生成不同的字符串.我能做些什么来阻止这个问题的发生吗?
帮助理解的基本结构:
App.js
import React from 'react';
import { connect } from 'react-redux';
const App = ({ randomStr }) => (
<div>
<p>{randomStr}</p>
</div>
);
const mapStateToProps = (state) => ({
...
});
const mapDispatchToProp = (dispatch) => ({
...
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
Run Code Online (Sandbox Code Playgroud)
而我的减速机:
reducer.js
import { generateString } from '../util';
import { NEW_STRING } from '../constants';
const stringReducer = (state = generateString(), action) => {
switch (action.type) {
case NEW_STRING:
return generateString();
default: …Run Code Online (Sandbox Code Playgroud) javascript reactjs server-side-rendering react-dom react-dom-server
ReactDOMServer.renderToString()我试图了解 React 16.8.6和React 16.8.6之间有什么区别ReactDOMServer.renderToStaticMarkup()。
这是我的理解:
\n\nrenderToStaticMarkup()当您只想渲染标记而不想在客户端对其进行水合时,在服务器端使用。(https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup)
renderToString()当您想使用该函数来ReactDOM.hydrate()水合客户端的应用程序时,在服务器端使用。(https://reactjs.org/docs/react-dom-server.html#rendertostring)
因此,如果我是对的,这两种方法之间的唯一区别是在应用程序的主要元素上renderToString()添加了。data-reactrootReact 在renderToStaticMarkup()文档中强调了这一点:
\n\n\n与 renderToString 类似,只不过这不会创建 React 内部使用的额外 DOM 属性,例如data-reactroot。如果您想使用 React 作为简单的静态页面生成器,这非常有用,因为剥离额外的属性可以节省一些字节。
\n\n如果您计划在客户端上使用 React 来使标记具有交互性,\n 不要使用此方法。相反,请在服务器上 使用renderToString并在客户端上使用ReactDOM.Hydrate() 。
\n
但是,我在 React 的存储库上阅读了这个问题,其中 Dan Abramov 说:
\n\n\n\n\n相反,使用Hydro()显式告诉 React 水合现有的\n HTML。那么它就不会依赖于 data-reactroot 是否存在。
\n
和:
\n\n\n …
所以我正在一个网站上工作,该网站需要具有以下路径的链接:
localhost:3000/visit/:name
Run Code Online (Sandbox Code Playgroud)
重定向到外部网址,例如 google.com?affiliateID=2。重定向需要是 nofollow,状态码为 307。
该应用程序是通用的;使用 express 和客户端 react 的服务器端渲染,两者都通过 react-router 使用共享路由。
路由.js
<Route status={307} path="visit/:slug" />
Run Code Online (Sandbox Code Playgroud)
服务器.js
app.use((req, res) => {
match({routes, location: req.originalUrl}, (err, redirectLocation, renderProps) => {
if (err) {
res.status(500).send(err.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
const html = renderToString(<RouterContext {...renderProps} />)
const isAffiliateLink = renderProps.routes.filter((route) => {
return route.status === 307
}).length > 0
if (isAffiliateLink) {
return res.redirect(307, "http://google.com")
}
const markup = renderToStaticMarkup(<Document html={html} …Run Code Online (Sandbox Code Playgroud) 从阵营16个文档有关ReactDOM.hydrate(),
与render()相同,但用于水合其内容由ReactDOMServer呈现的容器.React将尝试将事件侦听器附加到现有标记.
会不会ReactDOM.hydrate()也触发客户端上的生命周期方法,例如componentWillMount(),componentDidMount()在最初的呈现?
render()水合期间会在客户端调用方法吗?我想不会,因为这之间的区别ReactDOM.render()和ReactDOM.hydrate()?
如果render不在客户端上调用方法,我们就不会期望componentDidMount()触发生命周期方法.
如果在客户端上没有调用任何生命周期方法,我们如何知道React什么时候完成渲染.我想callback用以下语法:
ReactDOM.hydrate(element,container [,callback])
我想了解当React"试图将事件监听器附加到现有标记"时,是否存在可用的生命周期方法/钩子(可以更好地控制应用程序).
我们有一个使用样式化组件的 React 项目,其中的 ThemeProvider 提供了所有组件都应该能够引用的主题对象。在这个项目中,我们有一个传单地图,我们以标记的形式向其中添加 React 组件,使用ReactDOMServer.renderToString. 当它尝试访问theme组件的样式时,theme未定义。按照正常方式添加组件,即可正常工作。
我可以通过手动将主题对象导入到地图组件中,并将主题对象作为属性传递给标记组件来强制它工作,但这似乎有点老套 - 最好找出上下文的原因正在迷路。
在地图组件中:
const nodeContents = (
<NodeIcon_svg />
);
const nodeIcon = Leaflet.divIcon({html: ReactDOMServer.renderToString(nodeContents),
iconSize: [60, 60],
iconAnchor: [30, 30]
});
Leaflet.marker(latLng, { icon: nodeIcon }).addTo(_mapLayer);
Run Code Online (Sandbox Code Playgroud)
在 NodeIcon 组件的样式中(主题包含具有多种命名颜色的对象):
export const NodeIcon_svg = styled.svg`
polygon {
stroke: ${({ theme }) => theme.colors.blue1)};
fill: transparent;
}
`;
Run Code Online (Sandbox Code Playgroud)
如果我将其添加到地图组件中:
import themeColors from '../../theme';
Run Code Online (Sandbox Code Playgroud)
并将此行添加到添加 NodeIcon 的位置:
theme={themeColors}
Run Code Online (Sandbox Code Playgroud)
有用。但这是一种 hack - 它应该能够使用主题。
应该发生什么(当 NodeIcon 组件在其他地方使用时会发生什么):它找到颜色theme.colors并将其应用于多边形的笔画。 …
我正在尝试将一些图像注入我从 Markdown 创建的页面中。我正在尝试使用 ReactDomServer.renderToString()
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<Img fluid={data.allFile.edges[0].node.childImageSharp.fluid} />)
}
})
...
}
Run Code Online (Sandbox Code Playgroud)
img 显示为一个黑框,如果我右键单击该图像,我可以在新选项卡中打开它,该选项卡会显示应有的图像。
我在使用“react-dom/server”中的renderToString在 SSR 上渲染某些 URL 时遇到一些错误
\n我收到以下错误:
\nTypeError: Cannot read property 'length' of undefined\nat areHookInputsEqual (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:992:38)\nat Object.useMemo (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:1230:13)\nat useMemo (C:\\projects\\spd-web-app1\\node_modules\\react\\cjs\\react.development.js:1521:21)\nat Provider (C:\\projects\\spd-web-app1\\node_modules\\react-redux\\lib\\components\\Provider.js:22:41)\nat finishHooks (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:1077:16)\nat processChild (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:3046:14)\nat resolve (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:2962:5)\nat ReactDOMServerRenderer.render (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:3437:22)\nat ReactDOMServerRenderer.read (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:3375:29)\nat renderToString (C:\\projects\\spd-web-app1\\node_modules\\react-dom\\cjs\\react-dom-server.node.development.js:3990:27)\nRun Code Online (Sandbox Code Playgroud)\n我发现的是,在react-dom-server.node.development.js \xe2\x86\x92 createWorkInProgressHook()
\n我得到下面的对象,其中memoizedState不是数组。
\n{\n memoizedState: 0,\n queue: { last: null, dispatch: [Function: bound dispatchAction] },\n next: {\n memoizedState: { current: [QueryData] },\n queue: null,\n next: { memoizedState: [Object], queue: null, next: [Object] }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n … reactjs server-side-rendering react-dom react-dom-server react-hooks
为了改进 TTFB(第一个字节的时间),'PageSpeed Insights' 建议使用,ReactDOMServer.renderToNodeStream()但我不知道如何实现它。我阅读了rendertonodestream文章,但我不知道如何使用它。另外,我阅读了dev.to 文章,但在我的 next.js 应用程序中,没有 webpack.config.js 文件。如果我不能renderToNodeStream在 Next.js 中使用 react ,如何覆盖renderToNodeStreamNext.js 中的效果?
尝试打开构建项目时出现此错误
顺便说一下,项目在开发模式下运行良好。
Uncaught TypeError: Cannot read property 'hasOwnProperty' of undefined
at Object.<anonymous> (react-dom.production.min.js:760)
at m (bundle.js:1)
at Object.<anonymous> (index.js:34)
at m (bundle.js:1)
at Module.56 (main.2b9897ed.chunk.js:1)
at m (bundle.js:1)
at Object.36 (main.2b9897ed.chunk.js:1)
at m (bundle.js:1)
at l (bundle.js:1)
at Array.n (bundle.js:1)
Run Code Online (Sandbox Code Playgroud)
产生错误的行760。请注意,变量aa是require(“ react”);
var Tb = aa.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
Tb.hasOwnProperty("ReactCurrentDispatcher") || (Tb.ReactCurrentDispatcher = {
current: null
});
Run Code Online (Sandbox Code Playgroud)
这是我的package.json,正如您所注意到的,我使用了React和React-Dom的最新版本
{
"name": "xxxx",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-confirm-alert": "^2.4.1",
"react-dom": "^16.8.6",
"react-redux": "^7.0.2",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"redux": "^4.0.1"
},
"scripts": …Run Code Online (Sandbox Code Playgroud) 我正在使用 babel-register 在节点环境中使用 ES6 类,并希望使用 ReactDomServer 的 require( file_path ) 动态加载和渲染 React 组件,但它向我显示以下错误:
“不变违规:renderToStaticMarkup():您必须传递有效的 ReactElement。”
// enable es6
require('babel-register')({
"presets": ["es2015", "react"],
"extensions": [".jsx", ".js"]
});
// load component
var testComponent = require(testComponentPath);
console.log(testComponent); // { default: [Function: TestComponent] }
var html = ReactDomServer.renderToStaticMarkup(testComponent);
Run Code Online (Sandbox Code Playgroud) react-dom-server ×10
reactjs ×10
react-dom ×5
javascript ×2
webpack ×2
babeljs ×1
gatsby ×1
gatsby-image ×1
leaflet ×1
next.js ×1
node.js ×1
react-hooks ×1
react-router ×1