使用状态来自定义样式的react + styled-components

斯卡万

反应和样式化组件是新手,可能是由于不了解所有工作原理而陷入混乱。

让我们从头开始。我有一个简单的页面(App.js),该页面呈现两个组件“旋钮”。我想传递每个“旋钮”一个或多个属性,以便它可以计算其大小和其他相关的实例道具。在下面的示例中,一个已知的大小为200px,它的姐姐为100px。

import React from 'react';
import Knob from './components/knob.js'
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        hello world
        <Knob size={200} />
        <Knob size={100} />
      </header>
    </div>
  );
}

export default App;

到现在为止还挺好。现在在旋钮组件内部,我进行了所有转换,最终有了缩放的旋钮。该旋钮是基于svg的组件(在下面缩写,但很长,抱歉)。

所以-好消息是,这一切正常!但是我知道我正在解决这个错误。

为了使其工作并使用this.state.size来计算组件的合适字体大小,我不得不将样式化组件对象移到类中,并在类(Styles外部创建一个空的声明

所以-我的要求是双重的:

  1. 我认为我的方法在哲学上受到了损害……并且希望这里的专家能使我的大脑更混乱。
  2. 您将如何编辑代码以使其不仅正常工作,而且正常工作!

a)在我看来,整个Styles声明都属于该类之外。b)不知道为什么我必须两次引用this.state.xxxx c)我想我也在混合使用道具和状态。

除此之外,它是完美的(:。但是-正如您从下面的屏幕截图中所看到的...它实际上是有效的。

啊。

import React from 'react'
import { Knob, Pointer, Value, Scale, Arc } from 'rc-knob'
import styled from 'styled-components';


// this is my weird hack to get things working. Declare Styles outside of the class.
var Styles = {}

export default class MyKnob extends React.Component {
constructor(props) {
    super(props)
    
    this.state = {
        size: props.size,
        value: props.value,
        radius: (props.value/2).toString(),
        fontSize: (props.size * .2)
    }
    
    //Now define styles inside the class and i can use the fontsize that is derived from the size passed by the parent component!
    Styles = styled.div`
    .vpotText {
        fill: green;   
        font-size: ${this.state.fontSize+'px'};
    }
    `       
  }

// no idea why I need this block....but without it I get a whole bunch of 
// error TS2339: Property 'value' does not exist on type 'Readonly<{}>'.
state = {
    value: 50,
    size: 100,
    radius: '50',
    fontSize: 12

}
    
static defaultProps = { value: 50, size: 100};
 
render(){

    const customScaleTick = ({}) //abbreviated for readability.

    return (
        <Styles>
        <Knob size={this.state.size}  
            angleOffset={220} 
            angleRange={280}
            steps={10}
            min={0}
            max={100}
            // note use of this.state.value to set parameters that affect the sizing/display of the component
            value={this.state.value}
            onChange={value => console.log(value)}
        >
        <Scale steps={10} tickWidth={1} tickHeight={2} radius={(this.state.size/2)*0.84} color='grey' />
        <Arc arcWidth={2} color="#4eccff" background="#141a1e" radius = {(this.state.size/2)*0.76} />
        
        <defs>
        {/* GRADIENT DEFINITIONS REMOVED FOR READABILITY */}
        </defs>
            {/* NOTE: EXTENSIVE USE OF this.state.size TO ENSURE ALL PARTS OF THE COMPONENT ARE SCALED NICELY */}
            <circle cx={this.state.size/2} cy={this.state.size/2} rx={(this.state.size/2)*0.8} fill = "url(#grad-dial-soft-shadow)" />
            <ellipse cx={this.state.size/2} cy={(this.state.size/2)+2} rx={(this.state.size/2)*0.7} ry={(this.state.size/2)*0.7} fill='#141a1e' opacity='0.15' ></ellipse>
            <circle cx={this.state.size/2} cy={this.state.size/2} r={(this.state.size/2)*0.7} fill = "url(#grad-dial-base)" stroke='#242a2e' strokeWidth='1.5'/>
            <circle cx={this.state.size/2} cy={this.state.size/2} r={(this.state.size/2)*0.64} fill = 'transparent' stroke='url(#grad-dial-highlight)' strokeWidth='1.5'/>
            <Pointer width={(this.state.size/2)*0.05} radius={(this.state.size/2)*0.47} type="circle" color='#4eccff' />
            {/* THIS IS THE TRICKY ONE! */}
            {/* IN ORDER TO GET THE FONT SIZE RIGHT ON THIS ELEMENT (svg) I NEED THE STYLE */}
            <Value 
                marginBottom={(this.state.size-(this.state.fontSize)/2)/2}
                className="vpotText" 
            />
            
        </Knob>
    </Styles>
)}
}

这是输出的图片:

在此处输入图片说明

托马斯·冈萨雷斯(Tomas Gonzalez)

a)这是我们在样式化组件中使用props变量的方式:

const Styles = styled.div`
    .vpotText {
        fill: green;   
        font-size: ${props => props.fontSize}px;
    };
`;

b)这样,您无需两次调用状态

render(){
    return(
        <Styles fontSize={this.state.fontSize}>
           ...
       </Styles>
   )}

一旦掌握了样式化的组件,它们真的很酷。

d)另外,我建议您为它自己的组件赋值,而不是包装它并调用该类。

const StyledValue = styled(Value)`
       fill: green;   
       font-size: ${props => props.fontSize}px;
    `;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

styled-components-如何在html或body标签上设置样式?

React Styled-Components:参考其他组件

如何在React Styled-Components中设置子组件的样式

React Styled Components条件三元运算符

使用React Styled Components在两种类型的组件之间共享相同的样式

React Styled Components-如何访问原始HTML

styled-components表示在您的React组件(Component)周围包装了styled()

React Styled-Components主题-提供者动态主题

React Styled-Components 3个按钮大小

用React Styled-Components导入scss变量的最佳方法?

React + Styled Components-分离并重复使用CSS“捆绑包”

nextjs + react-native-web + styled-components:warnOnce

React Styled-Components-如何根据道具条件或伪类渲染样式?

React Styled-Components CSS向子元素添加!important

使用Styled-Components创建NPM包:Styled-Components TypeError:t.hasOwnProperty不是函数

styled-components:主题中的样式覆盖组件样式

在单文件组件方法中使用 vue-styled-components

如何在 Gatsby 2.0 中使用 styled-components 主题

React Styled-Components 传递道具问题

导入 .less 变量以在 React Styled Components 中使用

将 calc() 与 react-native 和 styled-components 一起使用时出错

如何在 React - typescript - Styled-components 应用程序中使用单击事件修改 DOM?

使用 React Styled Components,如何根据通过 useSelector 收集的状态声明颜色?

如何在 React Styled Components 中仅为一个道具制作多种样式?

styled-components 可以用来设置自定义组件的样式吗

nx React/Next.js styled-components 共享类型声明文件 styled.d.ts

Styled Components 渲染基于 props 的 Styled 标签

使用 Styled-Components 檢查多個道具

如何使用 styled-components 更改组件的颜色?