刚接触 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
)。
所以 - 我的要求有两个:
- 我认为我的方法在哲学上受到了损害......并且希望这里的专家能够解读我的大脑。
- 您将如何编辑代码,使其不仅可以正常工作,而且可以正常工作!
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>
)}
}
这是输出的图片:
最佳答案
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/