Как передать переменные темы Styled-Component в компоненты?

В моем приложении React+StyledComponent у меня есть такой файл темы:

тема.js:

const colors = {
  blacks: [
    '#14161B',
    '#2E2E34',
    '#3E3E43',
  ],
};

const theme = {
  colors,
};

export default theme;

В настоящее время я могу легко использовать эти цвета для стилизации своих компонентов следующим образом:

const MyStyledContainer = styled.div`
  background-color: ${(props) => props.theme.colors.blacks[1]};
`;

Проблема в том, как передать blacks[1] компоненту в качестве реквизита цвета для использования следующим образом:

<Text color="black[1]">Hello</Text>

Где Text.js:

const StyledSpan = styled.span`
  color: ${(props) => props.theme.colors[props.color]};
`;

const Text = ({
  color,
}) => {
  return (
    <StyledSpan
      color={color}
    >
      {text}
    </StyledSpan>
  );
};

Text.propTypes = {
  color: PropTypes.string,
};

export default Text;

В настоящее время вышеизложенное молча терпит неудачу и разрывает в DOM следующее:

<span class="sc-brqgn" color="blacks[1]">Hello</span>

Любые идеи о том, как я могу заставить это работать? Спасибо


person AnApprentice    schedule 14.04.2018    source источник


Ответы (4)


РЕДАКТИРОВАТЬ: обновлено для использования стилизованных компонентов withTheme HOC

Новый ответ

Вы можете обернуть рендеринг компонента <Text> в компонент более высокого порядка (HOC) withTheme, предоставленный styled-components. Это позволяет вам использовать тему, предоставленную <ThemeProvider>, непосредственно в компоненте React.

Пример (на основе документов по стилизованным компонентам):

import React from 'react'
import { withTheme } from 'styled-components'
import Text from './Text.js'

class MyComponent extends React.Component {
  render() {
    <Text color={this.props.theme.colors.blacks[1]} />;
  }
}

export default withTheme(MyComponent)

Тогда вы могли бы сделать

const MyStyledContainer = styled.div`
    background-color: ${(props) => props.color};
`;

Старый ответ

Вы можете импортировать тему, в которой вы рендерите и передаете <Text color={theme.blacks[1]} />.

import theme from './theme.js'
...
<Text color={theme.colors.blacks[1]} />

Тогда вы могли бы сделать

const MyStyledContainer = styled.div`
    background-color: ${(props) => props.color};
`;
person tskjetne    schedule 14.04.2018

Вы можете использовать defaultProps

import PropTypes from 'prop-types'

MyStyledContainer.defaultProps = { theme }
person Chasing Unicorn - Anshu    schedule 14.04.2018

App.js

Приложение получает тему и передает цвет тексту

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

const Text = styled.div`
  color: ${props => props.color || 'inherit'}
`

class App extends Component {
  render() {
    const { theme } = this.props
    return (
      <Text color={theme.colors.black[1]} />
    )
  }
}

export default App

Root.js

Корневой компонент передает тему всему приложению.

import React, { Component } from 'react'
import { ThemeProvider } from 'styled-components'
import theme from './theme'
import App from './App'

class Root extends Component {
  render() {
    return (
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    )
  }
}

export default Root
person Thomas Mirmo    schedule 14.04.2018

Если вы используете функциональные компоненты в React и v4.x и более поздние стилизованные компоненты, вам необходимо использовать useContext и ThemeContext стилизованных компонентов. Вместе они позволяют использовать настройки темы внутри компонентов, которые не являются стилизованными компонентами.

import { useContext } from 'react'
import { ThemeContext } from 'styled-components'
    
export default function MyComponent() {
      
  // place ThemeContext into a context that is scoped to just this component
  const themeProps = useContext(ThemeContext)

  return(
    <>
      {/* Example here is a wrapper component that needs sizing params */}
      {/* We access the context and all of our theme props are attached to it */}
      <Wrapper maxWidth={ themeProps.maxWidth }>
      </Wrapper>
    </>
  )
}

Дальнейшее чтение в документации по стилизованным компонентам: https://styled-components.com/docs/advanced#via-usecontext-react-hook

person serraosays    schedule 09.05.2021