使用样式化组件定义组件变体时的最佳做法?

时间:2019-11-24 10:25:41

标签: reactjs styled-components

通常,当我使用样式化组件时,我会在globals.js文件中定义一组标准组件,然后从那里导出它们。 G。像这样的标准段落样式:

export const P = styled.p`
    font-size: 1.4rem;
`

每种标准样式都可能带有变化e。 G。标准的粗体段落。我想知道实现此目标的最佳方法是什么。我可以看到几种方法:

方法1(通过粗体显示):

const P = styled.p`
    font-weight: ${({fontWeight}) => fontWeight ? fontWeight : 'normal'}
`

方法2(创建带有粗体道具的组件,但导出已经具有道具的单独组件):

export const BoldP = props => <P fontWeight="bold">

方法3 (分别定义和导出所有变体):

export const P = styled.p`
    font-weight: ${({fontWeight}) => fontWeight ? fontWeight : 'normal'}
`

export const BoldP = styled(P)`
    font-weight: bold
`

这个问题似乎有些亵渎,但是由于对于许多应用程序来说这是一个非常标准的界面,所以我想知道是否存在“正确”的方式来实现此目的。

1 个答案:

答案 0 :(得分:-1)

如果需要一些标准的共享值(例如主站点颜色),则需要全局样式化的组件主题。

首先创建全局主题上下文:

import React, { useEffect, useState } from 'react'
import { deepClone } from '@shared'
import { defaultGeneralTheme } from '../data/defaultGeneralTheme'
import { ThemeProvider, createGlobalStyle } from 'styled-components'

export const ThemeContext = React.createContext(null)

export const ThemeContextProvider = props => {
  const [generalTheme, setGeneralTheme] = useStateRo(deepClone(defaultGeneralTheme))

  return (
    <ThemeContext.Provider value={{ generalTheme, setGeneralTheme }}>
      <ThemeProvider theme={theme}>
        <>
          <GlobalStyle />
          {props.children}
        </>
      </ThemeProvider>
    </ThemeContext.Provider>
  )
}

const GlobalStyle = createGlobalStyle`
  body {  
    line-height: 1.2rem;
    background-color:  ${({ theme }) => theme.secondaryColor};
  } 
`

然后您可以创建可重复使用的组件:

import styled from 'styled-components'
import React, { forwardRef } from 'react'

export const Input = forwardRef(({ ...rest }, ref) => {
  return <StyledInput {...rest} ref={ref} />
})

const StyledInput = styled.input`
  color: ${({ theme }) => theme.textColor};
  width: 100%;
  text-align: center;
`

defaultGeneralTheme示例:

export const defaultGeneralTheme = {
    secondaryColor: '#ffffff',
    textColor: '#000000',
}

别忘了用提供程序包装顶级组件:

<ThemeContextProvider><App /></ThemeContextProvider>