reactjs ReactDOMServer.renderToStaticMarkup()中的MUI对话框不工作

unhi4e5o  于 2023-06-05  发布在  React
关注(0)|答案(1)|浏览(218)

我是第一次使用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]);
gxwragnw

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

相关问题