通过嵌套样式组件和 React 函数组件传递瞬态 props

问题描述 投票:0回答:2

我一直在努力处理样式组件和瞬态道具。请参阅下面的代码。

  • 我有一个样式组件,我们称之为
    StyledLabel
    ,它接收一个瞬态道具。
  • StyledLabel
    用于函数组件中,我们称之为
    IntermediateLabel
  • IntermediateLabel
    将收到的 props 传递给
    StyledComponent
  • IntermediateLabel
    在样式化组件中重新设计了样式,我们称之为
    ExtraStyledLabel

现在问题来了,当将瞬态 prop 传递给

ExtraStyledLabel
时,它并没有传递给
IntermediateLabel
。但是直接使用
IntermediateLabel
时,它会传递给
StyledLabel

功能组件不能重新设计吗?是我做错了什么还是bug?

这是代码,Codepen https://codepen.io/tengl/pen/abxgzdL

const { createRoot } = ReactDOM;
const { useState, forwardRef } = React;
const { createGlobalStyle } = styled;

const GlobalStyle = createGlobalStyle`
  html, body, #app {
    height: 100%;
    min-height: 100%;
  }
`;

const App = styled.div`
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
`;

const StyledLabel = styled.p`
    color: ${(p) => (p.$isSelected ? "green" : "red")};
    font-family: "Roboto Mono", monospace;
    font-size: 20px;
`;

// WORKS
const IntermediateLabelStyled = styled(StyledLabel)``;

// WORKS
const IntermediateLabelComponent = forwardRef(({ children, ...props }) => {
    console.log(props.$isSelected);
    return <StyledLabel {...props}>{children} </StyledLabel>;
});

// WORKS
const IntermediateLabelForwardRef = ({ children, ...props }) => {
    console.log(props.$isSelected);
    return <StyledLabel {...props}>{children} </StyledLabel>;
};

// WORKS
const ExtraStyledLabelStyledComponents = styled(IntermediateLabelStyled)`
    font-weight: bold;
    font-size: 30px;
`;

// DOES NOT WORK
const ExtraStyledLabelComponent = styled(IntermediateLabelComponent)`
    font-weight: bold;
    font-size: 30px;
`;

// DOES NOT WORK
const ExtraStyledLabelForwardRef = styled(IntermediateLabelForwardRef)`
    font-weight: bold;
    font-size: 30px;
`;

const Container = () => (
    <App>
        <GlobalStyle />
        <StyledLabel $isSelected>React 18 + styled-components 6. Transient props in intermediate components</StyledLabel>
        <StyledLabel $isSelected>Green text is ok, red is not</StyledLabel>
        <ExtraStyledLabelStyledComponents $isSelected={true}>With styled component</ExtraStyledLabelStyledComponents>
        <ExtraStyledLabelComponent $isSelected={true}>With React component</ExtraStyledLabelComponent>
        <ExtraStyledLabelForwardRef $isSelected={true}>With forwardRef</ExtraStyledLabelForwardRef>
        <IntermediateLabelComponent $isSelected={true}>Function component directly</IntermediateLabelComponent>
    </App>
);

const root = createRoot(document.getElementById("app"));
root.render(<Container />);
javascript reactjs styled-components
2个回答
0
投票

这似乎是设计使然。 https://github.com/styled-components/styled-components/issues/4266

我尝试过

shouldForwardProp
但无论如何都无法使其工作。

解决方案是将其重命名为普通道具。


0
投票

这是不可能的,因为它就是这样设计的。文档 (https://styled-components.com/docs/api#transient-props) 中指出:

如果你想阻止样式组件使用的 props 被传递到底层 React 节点或渲染到 DOM 元素,你可以在 prop 名称前加上美元符号 ($) 前缀,将其变成瞬态 prop。

这意味着 React 节点的行为是正确的,无法访问瞬态 props。您可以使用普通道具并手动过滤它们。

© www.soinside.com 2019 - 2024. All rights reserved.