React:将 CSSProperties 转换为 Styled-Component

Posted

技术标签:

【中文标题】React:将 CSSProperties 转换为 Styled-Component【英文标题】:React: Convert CSSProperties to Styled-Component 【发布时间】:2020-12-25 12:36:58 【问题描述】:

我有一个格式如下的对象:


    let style:React.CSSProperties|object = 
        marginLeft: '0',
        borderRadius: '20px',
        display: 'flex',
        justifyContent: 'center',
    

我需要将 React CSSProperties 转换为相应的字符串格式,例如:


    let string_styles:string = `
        margin-left: 0;
        border-radius: 20px;
        display: flex;
        justify-content: center;
    `

由于我找不到具体的语法来编写 css,例如 :hover::before::before:hover 内联,所以现在将其用作样式组件,同时保留 CSSProperties 对象以供将来导入.

不优雅,我硬编码了转换方法。

    deQuote(dict:object):string
        return JSON.stringify(dict).replace(/['"]+/g, '');
    
    // passin: marginLeft: '0', borderRadius: '20px' 
    // return: `marginLeft: 0, borderRadius: 20px`

    deBraces(str:string):string
        return str.substring(1, str.length-1);
    
    // passin: `marginLeft: 0, borderRadius: 20px`
    // return: `marginLeft: 0, borderRadius: 20px`

    deComma(str:string):string
        return str.split(',').join(';');
    
    // passin: `marginLeft: 0, borderRadius: 20px`
    // return: `marginLeft: 0; borderRadius: 20px`

    deBase(dict:object):string
        return deComma(deBraces(deQuote(dict)));
    
    // passin: marginLeft: '0', borderRadius: '20px' 
    // return: `marginLeft: 0; borderRadius: 20px`
    

但这里是棘手的部分,转换需要很多努力

    marginLeft -> margin-left

通过自定义函数解决,

    CSSPropertiesToComponent(dict:React.CSSProperties)
        let str = '';
        for(const [key, value] of Object.entries(dict))
            let clo = '';
            key.split('').forEach(lt=>
                if(lt.toUpperCase() === lt)
                    clo += '-' + lt.toLowerCase();
                else
                    clo += lt;
                
            );
            str += clo + ':' + value + ';';
        
        return str;
    

但是,如果有更好的方法将 React.CSSProperties 转换为 Styled Component 字符串,请告诉我。

【问题讨论】:

styled-components.com/docs/…? 【参考方案1】:

您可以使用 lodash.kebabCase package 来解决该问题。

这是一个例子

import kebabCase from 'lodash.kebabcase';

kebabCase('Foo Bar');
// => 'foo-bar'
 
kebabCase('fooBar');
// => 'foo-bar'
 
kebabCase('__FOO_BAR__');
// => 'foo-bar'

【讨论】:

我有一个类似的方法,我真的很期待一个更简单的解决方案。 deCap(str:string):stringreturn str.split('').map(lt=>lt.match(/[A-Z]/) && lt ? `-$lt.toLowerCase()` : lt).join('');谢谢你的建议。【参考方案2】:

为什么需要将对象转换为字符串?

您可以通过它映射并使用Object.keysArray.reduce 方法构建您的最终字符串。

const style = 
    marginLeft: '0',
    borderRadius: '20px',
    display: 'flex',
    justifyContent: 'center',


const finalResult = Object.keys(style).reduce((accumulator, key) => 
    // transform the key from camelCase to kebab-case
    const cssKey = kebabCase(key)
    // remove ' in value
    const cssValue = style[key].replace("'", "")
    // build the result
    // you can break the line, add indent for it if you need
    return `$accumulator$cssKey:$cssValue;`
, '')

如果您不想使用 kebabCase 库,可以使用简单的正则表达式查找所有大写字母并将其转换为小写字母并在其前加上 -

const regex = new RegExp(/[A-Z]/g)
const kebabCase = (str) => str.replace(regex, v => `-$v.toLowerCase()`)

【讨论】:

以上是关于React:将 CSSProperties 转换为 Styled-Component的主要内容,如果未能解决你的问题,请参考以下文章

CSSProperties TextAlignProperty 类型错误

将 React 组件转换为 Svelte

如何将 create-react-app 转换为 Preact?

将 React 应用程序转换为 React Native 的最快方法是啥?

将 React 组件转换为 Typescript?

如何将 React 路由器功能转换为 Typescript?