反应和样式化组件是新手,可能是由于不了解所有工作原理而陷入混乱。
让我们从头开始。我有一个简单的页面(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
)外部创建一个空的声明。
所以-我的要求是双重的:
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>
)}
}
这是输出的图片:
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] 删除。
我来说两句