简体   繁体   English

react + styled-components 使用 state 自定义样式

[英]react + styled-components using state to customize style

New to react and styled-components and have probably got myself in a muddle through not understanding how it all works. react 和 styled-components 的新手,可能因为不了解它是如何工作的而让自己陷入困境。

Let's start from the top.让我们从顶部开始。 I have a simple page (App.js) that renders two components "Knobs".我有一个简单的页面(App.js),它呈现两个组件“旋钮”。 I want to pass each 'Knob' one or more properties so it can calculate its size and other relevant instance props.我想向每个“旋钮”传递一个或多个属性,以便它可以计算其大小和其他相关的实例道具。 In the example below, one know is 200px in size, and it's sister is a 100px.在下面的例子中,一个知道是 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;

So far so good.到目前为止,一切都很好。 Now inside the Knob component, I do all my transformations and ultimately have a scaled Knob.现在在 Knob 组件中,我进行了所有的转换,最终得到了一个缩放的 Knob。 The knob is a svg based component (abbreviated below but still long, sorry).旋钮是基于 svg 的组件(以下缩写但仍然很长,抱歉)。

So - the good news is that it all works.所以 - 好消息是一切正常。 But I know I am approaching this wrong.但我知道我正在接近这个错误。

In order to get it to work and use the this.state.size to calculate the appropriate font size for the component, I had to move the styled-component object into the class...and create an empty declaration outside the class ( Styles ). In order to get it to work and use the this.state.size to calculate the appropriate font size for the component, I had to move the styled-component object into the class...and create an empty declaration outside the class ( Styles )。

So - my ask is two-fold:所以 - 我的问题有两个:

  1. I think my approach is philosophically damaged...and would love experts here to unscramble my brain.我认为我的方法在哲学上受到损害......并且希望这里的专家能够解读我的大脑。
  2. How would you edit the code to make it not just work, but work right!您将如何编辑代码以使其不仅可以工作,而且可以正常工作!

a) It seems to me that the entire Styles declaration belongs outside the class. a)在我看来,整个 Styles 声明属于 class 之外。 b) No idea why I have to reference this.state.xxxx twice c) I think I am also mixing up the use of props and state. b) 不知道为什么我必须引用 this.state.xxxx 两次 c) 我想我也混淆了道具和 state 的使用。

Other than that it's perfect (:. But -- as you see from the screenshot below...it actually works.除此之外,它是完美的(:。但是 - 正如您从下面的屏幕截图中看到的那样......它确实有效。

Ugh.啊。

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

here's a pic of the output:这是 output 的图片:

在此处输入图像描述

This looks like it would be a good use case for passing a prop into a Styled Component.这看起来像是将道具传递给样式化组件的一个很好的用例。 It would look something like this:它看起来像这样:

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

<Styles size={someSize}>
    ...
</Styles>

You can find the documentation here: https://styled-components.com/docs/basics#passed-props您可以在此处找到文档: https://styled-components.com/docs/basics#passed-props

a) This is how we use props variables in styled components: a) 这就是我们在样式化组件中使用 props 变量的方式:

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

b) That way you won't need to call the state twice b) 这样您就不需要调用 state 两次

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

styled-components are really cool once you get the hang of them.一旦你掌握了 styled-components 的窍门,它们就真的很酷了。

d) Also, I suggest you make value it's own component instead of wrapping it and calling the class. d) 另外,我建议您将其作为自己的组件进行赋值,而不是包装它并调用 class。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 React/Styled-components 继承样式 - How to inherit a style with React/Styled-components 如何在React Styled-Components中设置子组件的样式 - How to style child components in react styled-components React styled-components:如何设置隐式渲染组件的样式? - React styled-components: How to Style Implicitly Rendered Components? 如何使用样式组件自定义 react-select singleValue 字段 - How to customize react-select singleValue field with styled-components 如何使用样式组件全局设置动态反应数据 (dangerouslySetInnerHTML) 的样式? - How to globally style dynamic react data (dangerouslySetInnerHTML) with styled-components? 样式组件未将样式应用于自定义功能反应组件 - styled-components not applying style to custom functional react component 当 state 在 mousemove 上发生变化时反应样式组件的低性能 - React styled-components low performance when state changes on mousemove 关于使用React样式化组件对类组件进行样式化 - On styling of class components using React styled-components 如何使用样式组件和 React 高效地为组件添加变体 - How to efficiently add variants for components using styled-components and React 使用 styled-components 的 createGlobalStyle() 从文件创建全局样式 - Creating a global style from a file using styled-components' createGlobalStyle()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM