如何修复和报价“警告:uselayouteffect在服务器上无能为力”。在使用材料UI和ReactDomserver时?
我对ReactDomserver和Material UI主题提供商有一个问题。.一切正常 Fine ,但我一直在控制台上遇到这个烦人的错误:
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client.
到目前为止,我发现的所有解决方案都涉及我删除theaseprovider,但我想知道是否没有更好的解决方案?
代码:
const mapIcon = useMemo(() => {
let namePosition: MapPinProps['namePosition'] = 'bottom-start';
if (position.lng > 120) {
namePosition = 'bottom-end';
}
if (position.lng > 120 && position.lat < -80) {
namePosition = 'top-end';
}
if (position.lng <= 120 && position.lat < -80) {
namePosition = 'top-start';
}
const html = ReactDOMServer.renderToStaticMarkup(
<ThemeProviders>
<MapPin
active={isMapBuilder ? active : !completed}
highlight={highlightRequiredEvent}
icon={completed && doneIcon ? doneIcon : icon}
name={event?.type !== EVENTS_TYPE.ANIMATION || isMapBuilder ? name : ''}
rarity={rarity}
read={isMapBuilder || event?.type === EVENTS_TYPE.ANIMATION || read}
interactive={isMapBuilder || event?.type !== EVENTS_TYPE.ANIMATION}
selected={selected}
shape={shape}
size={iconSize}
userSettings={user.settings}
namePosition={namePosition}
locked={locked && !isMapBuilder}
isMapBuilder={isMapBuilder}
/>
</ThemeProviders>
);
return new L.DivIcon({
className: '',
// iconAnchor,
// popupAnchor,
iconSize: [iconSize, iconSize],
html: html.toString(),
});
}, [
position.lng,
position.lat,
event?.type,
isMapBuilder,
active,
completed,
highlightRequiredEvent,
doneIcon,
icon,
name,
rarity,
read,
selected,
shape,
iconSize,
user.settings,
locked,
]);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将尝试提供一些可以帮助解决这个问题的选择。我将在这里和那里做一些假设,在某些情况下让自己错了。
上下文
uselayouteffect(useLayouteffect() 。通常,服务器没有适当的处理方式。此外,官方文档还提到:
并提供一种修复它的方法,但它需要访问源代码(我想您没有)。
假设
&lt; thealeproviders/&gt; 组件
可能解决方案的源代码#1(可能是最好的吗?)
您可以尝试使用 reactdomserver.renderver.renderter.rendertertostostostostostostostostostostostostring() >代替 reactdomserver.rendertostaticmarkup()。
说明:假设您在服务器上使用它并在客户端上使用React,:
可能的解决方案#2(访问
themeproviders
组件源代码)您可以更改使用
uselayouteffect()
的使用的支票,并防止其在服务器上使用它您没有任何DOM。说明:根据 UseLayouteffect()和
useeffect()
之间选择。评论提及使用类似的内容:您可以在组件内使用此
usemorphiclayouteffect()
。可能的解决方案#3(不使用SSR)
您可以考虑删除
reactdomserver
的使用。说明:这似乎是一个非常简单的组件,与服务器渲染相比,选择在客户端上渲染它的成本可能微不足道。 注意:选择删除SSR之前,您可以将此决定基于一些基准和测试。
我希望其中一些可以帮助您!
I'll try to give some options that could help on solving that. I'll make some assumptions here and there, allowing myself to be wrong in some cases.
Context
useLayoutEffect()
only fires after DOM mutations. In general, servers don't have a proper way of handling that. Also, the official doc also mentions:and gives a way of fixing it but it requires access to the source code (which I suppose you don't have).
Assumptions
<ThemeProviders />
componentPossible Solution #1 (Possibly best one?)
You could try to use ReactDOMServer.renderToString() instead of ReactDOMServer.renderToStaticMarkup().
Explanation: Supposing that you are using this on the server and using React on the Client, according to the official docs about ReactDOMServer.renderToStaticMarkup():
Possible Solution #2 (With access to
ThemeProviders
component source code)You could change the check for the usage of
useLayoutEffect()
and prevent it from using it at the server, where you don't have any DOM.Explanation: According to this comment inside an Issue at GitHub, it suggest choosing between
useLayoutEffect()
anduseEffect()
based on the existence of the DOM. The comment mention about using something like:And you could use this
useIsomorphicLayoutEffect()
inside your component.Possible Solution #3 (not use SSR)
You could consider removing the usage of the
ReactDOMServer
.Explanation: This seems to be a very simple component and the cost of choosing to render it on Client could be insignificant compared to the server render. NOTE: Before choosing to remove the SSR you could base this decision on some benchmarks and tests.
I hope that some of this could help you!