如何同时使用属性扩展和提取属性

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

How to use prop spreading and extracting props at the same time

问题

我有两个组件,像这样

const TextLarge = (props) => { // props are classes, color and children
    return <Text
               classes={'text-large-style'}
               {...props}>
               {props.children}
           </Text>
}

const Text = ({
    children,
    color,
    classes,
}) => {
    return <p
               className={clsx('text-styles', classes)}
               style={{ color: color }}>
               {children}
           </p>
}

现在,当我将一个 class 传递给 <TextLarge />

<TextLarge
    classes='some-special-style'>
    Foo
</TextLarge>

这会覆盖 classes='text-large-style',因为 {...props}classes='some-special-style' 展开到 <TextLarge/> 之后 classes='text-large-style'

是否有一种(React/优雅)的方法将 classesprops 中取出,以便实现以下的效果

const TextLarge = (props) => { // props are classes, color, and children
    return <Text
               classes={clsx('text-large-style', props.classes)}
               {...props}> // no classes in here
               {props.children}
           </Text>
}

但仍然将其余的 {...props} 展开到 <Text /> 中?
我知道这可能会改变顺序,使得 classes={clsx('text-large-style', props.classes)} 覆盖 {...props}

const TextLarge = (props) => { // props are classes, color, and children
    return <Text
               {...props}
               classes={clsx('text-large-style', props.classes)}>
               {props.children}
           </Text>
}

但我想要更多的控制。

英文:

I have two components like this

const TextLarge = (props) =&gt; { // props are classes,color and children
    return &lt;Text
               classes={&#39;text-large-style&#39;}
               {...props}&gt;
               {props.children}
           &lt;/Text&gt;
}

const Text = ({
    children,
    color,
    classes,
}) =&gt; {
    return &lt;p
               className={clsx(&#39;text-styles&#39;, classes)}
               style={{color: color}}&gt;
               {children}
           &lt;/p&gt;
}

Now, when I pass a class to &lt;TextLarge /&gt;

&lt;TextLarge
    classes=&#39;some-special-style&#39;&gt;
    Foo
&lt;TextLarge&gt;

This overwrites classes=&#39;text-large-style&#39; because {...props} spreads classes=&#39;some-special-style into &lt;TextLarge/&gt; after classes=&#39;text-large-style.

Is there a (React/elegant) way to take classes out of props, so something like

const TextLarge = (props) =&gt; { // props are classes,color and children
    return &lt;Text
               classes={clsx(&#39;text-large-style&#39;, props.classes)}
               {...props}&gt; // no classes in here
               {props.children}
           &lt;/Text&gt;
}

yet still spreading the rest of the {...props} into &lt;Text /&gt;?
I know that could change the order, making classes={clsx(&#39;text-large-style&#39;, props.classes)} overwrite {...props}

const TextLarge = (props) =&gt; { // props are classes,color and children
    return &lt;Text
               {...props}
               classes={clsx(&#39;text-large-style&#39;, props.classes)}&gt;
               {props.children}
           &lt;/Text&gt;
}

but I want more control.

答案1

得分: 1

是的,你可以使用解构和剩余属性(rest)来取出 classes:

const TextLarge = ({classes, ...rest}) => {
    // ...
};

实际上,你可能还想移除 children

const TextLarge = ({classes, children, ...rest}) => {
    // ...
};

然后 ...rest 将不包括 classes(或 children),如果你想要传递它们,你可以在明确的属性中包括 classes

const TextLarge = ({classes, children, ...rest}) => {
    return (
        <Text {...rest} classes={`text-large-style ${classes ?? ""}`}>
            {children}
        </Text>
    );
};
英文:

> Is there a (React/elegant) way to take classes out of props

Yes, you can use destructuring with a rest target:

const TextLarge = ({classes, ...rest}) =&gt; {
    // ...
};

Actually, you probably want to remove children as well:

const TextLarge = ({classes, children, ...rest}) =&gt; {
    // ...
};

Then ...rest won't include classes (or children), and you can include classes in your explicit prop (if you want to pass them on):

const TextLarge = ({classes, children, ...rest}) =&gt; {
    return (
        &lt;Text {...rest} classes={`text-large-style ${classes ?? &quot;&quot;}`}&gt;
            {children}
        &lt;/Text&gt;
    );
};

huangapple
  • 本文由 发表于 2023年2月8日 17:56:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384046.html
匿名

发表评论

匿名网友

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

确定