javascript - React + styled-components 使用状态来自定义样式

标签 javascript reactjs styled-components

刚接触 React 和样式组件,可能因为不了解其工作原理而陷入困境。

让我们从顶部开始。 我有一个简单的页面(App.js),它呈现两个组件“旋钮”。 我想传递每个“旋钮”一个或多个属性,以便它可以计算其大小和其他相关实例 Prop 。在下面的示例中,我们知道尺寸为 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) 我认为我也混淆了 props 和 state 的使用。

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

呃。

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>
)}
}

这是输出的图片:

enter image description here

最佳答案

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;
    `;

关于javascript - React + styled-components 使用状态来自定义样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61811464/

相关文章:

javascript - Polymer 中的 <content> 和 <shadow> 标签有什么区别?

javascript - 使用位置 : 'Absolute' and display: 'None' in React Native still renders the component

javascript - react 模棱两可的错误消息 : "Check the render method of ` Constructor`.“

html - 如何将 Logo 放在顶部,将页脚放在底部?

reactjs - 使用样式组件向子元素添加样式?

javascript - 如何将输入的 ng-model 值推送到 Angular 中的表中?

javascript - 如何从 json stringify 数组获取所需的输出

javascript - 小javascript这个问题

css - 类型 'string' 不可分配给类型 'Position'

javascript - 我可以在 Styled Component 中设置 Child 的 css 吗?