可以将基本的JSX渲染为在render方法内调用的函数吗?

huangapple go评论48阅读模式
英文:

Is it okay to render basic JSX as an invoked function inside the render method?

问题

在我们的代码库中,我一直遇到这种在render方法内部调用renderXelement()的模式。我听说这对于React来说并不是一种很常见的模式。此外,我想知道是否有必要尽量避免这种模式,从某种意义上说它有哪些不利之处(如果有的话)。

请看 renderCollapsedLinks()。我删除了一些多余的代码,以使问题更清晰。

示例:

export function NavigationDropdownLinksOverlay({
    activeDropdownLink,
    onClickBack,
}: NavigationDropdownLinkOverlay) {
    const { classes } = useStyles();

    const renderCollapsedLinks = (groupLink: DropdownGroupLinks) => {
        return groupLink.links.map((link, index) => (
            <Box mb={index !== groupLink.links.length - 1 ? 'sm' : 0}>
                <Link href={link.link} className={classes.anchorLink}>
                    {link.label}
                </Link>
            </Box>
        ));
    };

    return (
        <MobileNavigationOverlay show={!!activeDropdownLink}>
            <MobileMenuBanner title={activeDropdownLink?.label || ''} />
            <BackButton onClick={onClickBack} />
            <Grid gutter={0} className={classes.linkGridFullWidth}>
              {renderCollapsedLinks()} 
            </Grid>
        </MobileNavigationOverlay>
    );
}

请注意,我并没有回答是否应该避免这种模式的问题,而只是提供了代码的翻译部分。

英文:

In our codebase, I keep coming across this pattern of invoking renderXelement() inside the render method. I have heard that it is not a very common pattern for React. Also, I was wondering whether is a thing to avoid at all costs, in a sense that what kind of downsides it has (if any).

See renderCollapsedLinks(). I removed some of the excessive code to make the question more clear.

Example:

export function NavigationDropdownLinksOverlay({
    activeDropdownLink,
    onClickBack,
}: NavigationDropdownLinkOverlay) {
    const { classes } = useStyles();

    const renderCollapsedLinks = (groupLink: DropdownGroupLinks) =&gt; {
        return groupLink.links.map((link, index) =&gt; (
            &lt;Box mb={index !== groupLink.links.length - 1 ? &#39;sm&#39; : 0}&gt;
                &lt;Link href={link.link} className={classes.anchorLink}&gt;
                    {link.label}
                &lt;/Link&gt;
            &lt;/Box&gt;
        ));
    };

    return (
        &lt;MobileNavigationOverlay show={!!activeDropdownLink}&gt;
            &lt;MobileMenuBanner title={activeDropdownLink?.label || &#39;&#39;} /&gt;
            &lt;BackButton onClick={onClickBack} /&gt;
            &lt;Grid gutter={0} className={classes.linkGridFullWidth}&gt;
              {renderCollapsedLinks()} 
            &lt;/Grid&gt;
        &lt;/MobileNavigationOverlay&gt;
    );
} 

答案1

得分: 1

当然,你可以使用函数来计算一个值。即使在React中,即使这个值是JSX。

你甚至可以更进一步,将这个函数移到组件之外。这样做不仅让组件更易阅读,还有一个优势,即这个函数不再在每次渲染时都被创建:

export function NavigationDropdownLinksOverlay({
    activeDropdownLink,
    onClickBack,
}: NavigationDropdownLinkOverlay) {
    const { classes } = useStyles();

    return (
        <MobileNavigationOverlay show={!!activeDropdownLink}>
            <MobileMenuBanner title={activeDropdownLink?.label || ''} />
            <BackButton onClick={onClickBack} />
            <Grid gutter={0} className={classes.linkGridFullWidth}>
                {renderCollapsedLinks(groupLink.links, classes)}
            </Grid>
        </MobileNavigationOverlay>
    );

}

// renderCollapsedLinks现在是一个纯函数,仅依赖于函数参数来生成返回值。
const renderCollapsedLinks = (links, classes) => {
    const last = links.length-1;

    return links.map((link, index) => (
        // 你应该为<Box />添加一个`key`
        <Box mb={index !== last ? 'sm' : 0}>
            <Link href={link.link} className={classes.anchorLink}>
                {link.label}
            </Link>
        </Box>
    ));
};
英文:

Of course you can use functions to compute a value. Even in React, even if this value is JSX.

You can even go a step further and move this function out of the component. This makes imo. the component more readable and has the advantage that this function is no longer created on every render:

export function NavigationDropdownLinksOverlay({
    activeDropdownLink,
    onClickBack,
}: NavigationDropdownLinkOverlay) {
    const { classes } = useStyles();

    return (
        &lt;MobileNavigationOverlay show={!!activeDropdownLink}&gt;
            &lt;MobileMenuBanner title={activeDropdownLink?.label || &#39;&#39;} /&gt;
            &lt;BackButton onClick={onClickBack} /&gt;
            &lt;Grid gutter={0} className={classes.linkGridFullWidth}&gt;
                {renderCollapsedLinks(groupLink.links, classes)}
            &lt;/Grid&gt;
        &lt;/MobileNavigationOverlay&gt;
    );

}

// renderCollapsedLinks is now a pure function and relies only on the function arguments to produce the returned value.
const renderCollapsedLinks = (links, classes) =&gt; {
    const last = links.length-1;

    return links.map((link, index) =&gt; (
        // you should add a `key` to `&lt;Box /&gt;`
        &lt;Box mb={index !== last ? &#39;sm&#39; : 0}&gt;
            &lt;Link href={link.link} className={classes.anchorLink}&gt;
                {link.label}
            &lt;/Link&gt;
        &lt;/Box&gt;
    ));
};

huangapple
  • 本文由 发表于 2023年6月26日 15:24:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76554402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定