首页 > 解决方案 > 仅将道具从 JS 传递给 CSS-in-JS 一次

问题描述

我正在使用带有 @emotion/react 库的 React 和 CSS-in-JS 开发可重用的侧边栏

我有一个 ReactComponent ,它返回如下内容:

 return (
    <s.SidebarContainer 
        backgroundImage={backgroundImage} 
        isOpen={isOpen}>
        <s.TogglerContainer 
            onClick={() => setIsOpen(!isOpen)} 
            isOpen={isOpen}>
        </s.TogglerContainer>
        <s.SidebarHeader 
        font={fonts.header}
        >
            {header}
        </s.SidebarHeader>
        <s.MenuContainer>{menuItemsJSX}</s.MenuContainer>
    </s.SidebarContainer>
)

如您所见,我将道具附加到每个样式组件。这是我的 style.js:

import styled from '@emotion/styled';


export const SidebarContainer = styled.div`
width: ${p => p.isOpen ? '18%' : '5%'} ;
background-image: 
linear-gradient(
    315deg,
    rgba(252,82,150,0.8) 0%,
    rgba(246,112, 98, 0.8) 74%),
    url(${p => p.backgroundImage}
);
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
color: white;
position: relative; // Toggler
transition: .2s ease-in all;

@media (max-width: 576.97px){ 
    width: ${p => p.isOpen ? '80%' : '15%'} ;
}

@media (min-width: 577px) and (max-width: 992px){ 
    width: ${p => p.isOpen ? '30%' : '7%'} ;
}
`


export const SidebarHeader = styled.h3`
text-align: center;
height:10%;
margin-top: .5em;
letter-spacing: .1em;
font-size: 1em;
font-family: ${p => p.font};
overflow: hidden;
padding: 0em .3em;
`

export const TogglerContainer = styled.div`
    position: relative;
    
    &:after{
        ${p => p.isOpen ? `content:'<';`
                        : `content:'>';`}
        text-align:center;
        position:absolute;
        background-color: #E58C8A;
        background-image: linear-gradient(315deg, #E58C8A 0%, #EEC0C6 74%);
        right:0;
        transform: translateX(12px);
        width: 24px;
        height: 24px;
        margin-top:2em;
        border-radius: 50%;
        color:rgb(19,15,64);
        box-shadow: 4px 2px 2px rgba(0,0,0,0.3);
        transition:  .2s ease-in box-shadow;
    }
    &:hover{
        &:after{
            box-shadow: 5px 3px 3px rgba(0,0,0,0.3);
            transition:  .2s ease-in all;
        }
    }

    `

我只是放了一部分代码以避免填满你的显示。我的问题是:

有一些方法可以将道具发送到 .style.js 文件一次(通过文件而不是通过组件),然后在 .style.js 文件中接收它并在全球范围内使用它?

例如,我想要这样的东西,

  <s.SidebarContainer 
    backgroundImage={backgroundImage} >
    <s.TogglerContainer 
        onClick={() => setIsOpen(!isOpen)}>

(看看我删除了什么isOpen={isOpen}

标签: javascriptcssreactjscss-in-js

解决方案


您必须为依赖于该道具的每个样式化组件提供该道具。

每个 styled 组件都是一个 react 组件,当 props 发生变化时,emotion 会重新渲染组件,让你可以根据 props 调整样式。不可能isOpen只将状态传递给一个样式化组件并与其他样式化组件共享该状态,因为每个组件都必须isOpen通过自己的 props 接收状态。


推荐阅读