【问题标题】:Is there a way to access the properties of a an imported component upon its drawing is complete in React?有没有办法在 React 中完成绘图后访问导入组件的属性?
【发布时间】:2022-09-27 19:41:01
【问题描述】:

我正在开发一个 UI,可以将数学公式的图像与通过 DL 模型从该图像生成的 LaTeX 代码的渲染版本进行比较。为此,我想将两个元素(sourceImage 和渲染代码)放在另一个下方。现在,为了简化比较,让两个元素具有相同的大小将是有益的。为了渲染乳胶代码,我使用包better-react-mathjax。不幸的是,有了这个包,我只能选择设置字体大小,而不是生成的渲染组件的宽度。因此,我想知道是否可以以某种方式根据渲染代码的宽度设置图像元素的宽度。我试图用 refs 来实现这一点,但是这些不能在 MathJax 组件上使用。

       <Grid container>
          <Grid item>
            <fieldset>
              <legend>Original formula image</legend>
              <Box>
                <img
                  width={imageWidth}
                  src={sourceImage}
                  alt=\"Input image\"
                />
              </Box>
            </fieldset>
          </Grid>
          <Grid item>
            <fieldset>
              <legend>Dynamically rendered (corrected) formula</legend>
              <Box>
                <MathJax className={classes.mathjaxElement} dynamic={true}>{\'$$\' + texSource + \'$$\'}</MathJax>
              </Box>
            </fieldset>
          </Grid>
        </Grid>

编辑

为了更准确地说明我想要实现的目标,以下是上述代码当前呈现的图像。我试图实现的是,上框中的图像与下图中的公式具有相同的宽度(其宽度由其中的公式定义)。

Image with the current rendering output

  • 我认为您应该尝试使用 itemRef 属性而不是 ref。这个好像支持
  • 您应该能够为MathJax 组件指定widthminWidthmaxWidth,并且容器将使用该css...只需像您所做的那样传递className 中的类...或您可以只用所需宽度的元素包装MathJax 元素。尽管如此,如果生成的乳胶更宽,您会遇到一些问题(取决于乳胶中是否有换行符)。如果您希望这些盒子具有相同的宽度,只需将它们都放在具有列方向的弹性盒子中,然后使顶部盒子弯曲以适应较小盒子的宽度。
  • 听起来这更像是与 CSS 和 HTML 相关的问题,而不是 Latex 输出......我的意思是,Latex 只能通过字体大小属性来控制(你不能在没有非常特别的额外措施......你也不应该。只需在这些元素上设置一个最小宽度,然后使它们都成为其父容器的 100%(或将 flex 属性设置为拉伸),你应该没问题。
  • 非常感谢您花时间对我的问题发表评论。恐怕这不是我要找的。我对问题进行了编辑,提供了更多信息和输出当前外观的图像。如果您对此有其他想法,请告诉我。
  • 嗯..好的,看起来不错..您希望图像中的数学具有与渲染数学完全相同的高度?您可以将 mathjax 内容放在 div 中,然后将 ref 添加到该 div 中,因为它会随着内容的增长而增长...可能很难使其完美,因为您不知道数学周围的空白量图像,我假设?那么,您是否希望图像具有完全相同的高度?

标签: javascript reactjs mathjax


【解决方案1】:

好的,所以这涉及到很多 React 和网络“东西”才能工作。

首先,better-react-mathjax 是我的库,确实我们不能将ref 传递给它。但是,感谢您的帖子,我将确保在将来的版本中启用回调引用(例如,一个接受引用并对其进行处理的函数)。但是,引用的所有权必须保留在 MathJax 类中,因为它对于组件的工作至关重要。

尽管如此,考虑到您的用例,实际上没有必要将 ref 附加到 MathJax 组件本身。所有你想知道的是 Latex 内容的宽度,这可以通过将MathJax 组件放在另一个随内容增长的元素中来完成。这种方法产生的任何问题都可能出现在将引用直接附加到MathJax 组件上的方法(如果可能的话),所以在这里,MathJax 组件中缺少此功能不是问题。

所以计划是让图像具有与生成的 Latex 相同的宽度。不好的是,这存在一些我们可能不得不接受的固有问题:

  • 我们不知道图像中数学的填充。我假设最终目标是让公式具有相似的大小,但如果图像本身的公式在大量空白处居中,那么将图像大小调整为输出 Latex 大小不一定会使数学大小相同。
  • 您必须为输出 Latex 选择一些字体大小。也许您可以根据输入图像的大小动态确定这一点,但那是另一章。结果,生成的大小可能总是与输入大小不同,因为我们对其大小一无所知(您可以使用transform 将元素缩放到某个大小,从而避免选择合适的字体大小的问题,但我也不确定这是否是最优的)。

鉴于我们接受上述情况,计划如下:

  1. 在随内容增长的元素内渲染 Latex。
  2. 测量包含 Latex 的元素的最终宽度。
  3. 将图像的宽度设置为等于上一步中获取的宽度。

    这可以通过多种方式完成。正如您已经看到的,当useEffect 触发时,生成的元素宽度可能不是最终宽度,因此为了解决这个问题,我们可以设置一个超时以在元素渲染后的一小段时间触发最终宽度应该随时可用:

    setTimeout(
        () => setWidth(ref.getBoundingClientRect().width),
        100
    );
    

    其他重要的细节是包含 Latex 的元素应该是随内容扩展的元素,例如例如,不是块元素。

    我为你准备了一个沙箱作为概念证明:https://codesandbox.io/s/user-example-16-so73825659-wkgd96

    尝试单击按钮并验证当数学发生变化时,图像也会改变其宽度。

    希望您可以从中概括并解决您的用例!

【讨论】:

    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 2022-11-13
    • 2022-08-02
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    相关资源
    最近更新 更多