我是第一次使用DIALOG组件,并认为它在我的设置中无缝工作。不幸的是,它没有,在打破了我的头很长一段时间后,我怀疑这是因为我正在使用的ReactDOMServer.renderToStaticMarkup()。
我试图在ReactDOMServer.renderToStaticMarkup()返回的JSX中使用MUI对话框。
虽然我没有在服务器端呈现这一点,但我这样做是因为@types/d3-org-chart要求nodeContent函数的返回类型为字符串。直到我添加了一个内部nodeContent,一切都正常工作。现在,当我单击时,我希望打开一个对话框并显示数据。相反,它只是在控制台中抛出这个警告,什么也不做。我怀疑这可能是由于我使用ReactDOMServer.renderToStaticMarkup()将JSX转换为字符串。是MUI对话框/模态在SSR中不工作吗?有没有办法在我的场景中创建一个对话框,或者我不应该使用ReactDOMServer.renderToStaticMarkup()将其转换为字符串?
浏览器控制台警告:
Clicked on this button with event [object PointerEvent] data data,height,depth,parent,id,children,width,x0,y0,firstCompact,compactEven,flexCompactDim,firstCompactNode,x,y
Clicked on this button with event [object PointerEvent] data [object Object],150,0,,ST-33,[object Object],[object Object],[object Object],[object Object],375,0,0,,,,,0,0
Clicked on this button with event [object PointerEvent] data ST-33
Clicked on this button with event [object PointerEvent] data 12
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. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
at ButtonBase (http://127.0.0.1:3000/static/js/bundle.js:8585:22)
at WithStyles (http://127.0.0.1:3000/static/js/bundle.js:25770:31)
at Button (http://127.0.0.1:3000/static/js/bundle.js:8342:24)
at WithStyles (http://127.0.0.1:3000/static/js/bundle.js:25770:31)
at div
at FullScreenDialog (http://127.0.0.1:3000/static/js/bundle.js:2626:19)
at div
at div
at div
Open variable is changed and is set to true
代码段:
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import { TransitionProps } from '@material-ui/core/transitions';
import Slide from '@material-ui/core/Slide';
import Button from '@material-ui/core/Button';
export const InternalDirectoryStructure = (props: InternalStructProps) => {
const d3Container = useRef(null);
//let chart = null;
let [chart, setChart] = React.useState(new OrgChart<UserData>());
const handleClose = () => {
setOpen(false);
};
const [open, setOpen] = React.useState(false);
useLayoutEffect(() => {
console.log(`Open variable is changed and is set to ${open}`)
}, [open]);
chart
.nodeContent(function (d: any, i, arr, state) {
let nodeColor = '#904C3F';
const nodeStyling: CSS.Properties = {
fontFamily : 'arial',
backgroundColor : nodeColor,
position: 'absolute',
marginTop : '-1px',
marginLeft: '-1px',
width: `${d.width}px`,
height: `${d.height}px`,
borderRadius: '10px',
}
const nodeReporteeStyling: CSS.Properties = {
color: '#ffffff',
marginRight: '30px',
marginTop: '15px',
textAlign: 'right',
}
const nodeCenterContentStyling: CSS.Properties = {
padding: '20px',
paddingTop: '5px',
textAlign: 'center',
}
const nodeNameStyling: CSS.Properties = {
color: '#ffffff',
fontSize: '24px',
fontWeight: 'bold',
}
const nodePositionNameStyling: CSS.Properties = {
color: '#ffffff',
fontSize: '24px',
marginTop : '4px',
}
const nodeLineStyling: CSS.Properties = {
borderBottom : '1px solid white',
}
return ReactDOMServer.renderToStaticMarkup(
<div style={nodeStyling}>
<div style={nodeReporteeStyling}>
<Badge className={'reportees'} badgeContent={d.data.reporteeCount} color="primary">
<PeopleIcon/>
</Badge>
<Dialog fullScreen open={open} onClose={handleClose} TransitionComponent={Transition}>
<IconButton edge="start" color="inherit" onClick={handleClose} aria-label="close">
<CloseIcon />
</IconButton>
<DialogContent>
Hello
</DialogContent>
</Dialog>
</div>
<div style={nodeCenterContentStyling}>
<div style={nodeNameStyling}> {d.data.displayFeName}</div>
<div style={nodePositionNameStyling}> {d.data.displayFeLabel || ''} </div>
<br/>
<div style={nodeLineStyling}> </div>
</div>
</div>
)
})
.nodeUpdate(function (d: any) {
select(this)
.select('.node-rect')
.attr('stroke', (d: any) =>
d.data._highlighted || d.data._upToTheRootHighlighted
? '#FFFFFF'
: 'none'
)
.attr(
'stroke-width',
d.data._highlighted || d.data._upToTheRootHighlighted ? 15 : 1
);
select(this).on('click.node-update',(event,data: any)=>{
if ([...event.srcElement.classList].includes("node-button-foreign-object")) {
chart.clearHighlighting();
chart.setUpToTheRootHighlighted(data.id).render();
}
});
select(this)
.select('.reportees').on('click',(event,d: any)=>{
console.log(`Clicked on this button with event ${event} data ${Object.keys(d)}`)
console.log(`Clicked on this button with event ${event} data ${Object.values(d)}`)
console.log(`Clicked on this button with event ${event} data ${d.id}`)
console.log(`Clicked on this button with event ${event} data ${d.data.reporteeCount}`)
setOpen(true)
})
})
.onNodeClick(function (d:any) {
chart.clearHighlighting();
chart.setUpToTheRootHighlighted(d).render();
//If Node has some reportee count then we need to display the reportee contact
let nodeData:UserData = props.data.find((obj:UserData) => obj.id === d);
})
.render().fit();
select(d3Container.current).style(
'background-color', '#333333',
)
}, [props.data, d3Container.current]);
1条答案
按热度按时间gxwragnw1#
在互联网上进行了一些研究后,有两种解决方案可以尝试:
1.尝试
renderToString()
而不是renderToStaticMarkup()
。但是,我注意到您没有使用任何SSR。1.这似乎是当组件在
useLayoutEffect
事件循环中呈现时的问题。使用antd + next.js和react + antd的人报告了相同的错误,来自这个github问题:https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85?permalink_comment_id=3672883#gistcomment-3672883添加此软件包
useIsomorphicLayoutEffect
可能会解决您的问题。你可以下载这个包:
npm i use-isomorphic-layout-effect
查看此markdown页面以了解有关软件包的更多信息:https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85?permalink_comment_id=3318852#gistcomment-3318852