React入门系列教程(七)使用className和内联样式

2019-03-09  本文已影响0人  du1dume

先看看用内联样式方式给react组件加样式:

<div id="rootElement"></div>
<script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<script type="text/babel">
    const rootElement = document.getElementById('rootElement')
    const styleElement = (
        <div>
            <!--可以忽略px,react默认把数字视为px-->
            <div style={{paddingLeft: '30px'}}>我是一个盒子</div>
        </div>
    )
    ReactDOM.render(styleElement, rootElement)
</script>

我们看到与HTML不同的是,JSX中传递给style属性的是个对象,而HTML中是字符串。另外CSS属性的名字是以驼峰风格书写的,属性值为字符串。

下面看看如何使用className

<div id="rootElement"></div>
<script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
    .box {
        border: 1px solid red;
    }
    
    .box-small {
        width: 50px;
        height: 50px;
    }
    
    .box-medium {
        width: 100px;
        height: 100px;
    }
    
    .box-large {
        width: 150px;
        height: 150px;
    }
</style>
<script type="text/babel">
    const rootElement = document.getElementById('rootElement')
    const styleElement = (
        <div>
            <div className="box box-small" style={{paddingLeft: '30'}}>我是一个盒子</div>
        </div>
    )
    ReactDOM.render(styleElement, rootElement)
</script>

我们看到在JSX中应用样式名的话使用的属性是className,在HTML中class

看起来更清晰的写法:

const props = {
    className="box box-small",
    style={{paddingLeft: 30}},
}

<div {...props}></div>

下面我们把组件编程函数组件:

<div id="rootElement"></div>
<script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
    .box {
        border: 1px solid red;
    }
    
    .box-small {
        width: 50px;
        height: 50px;
    }
    
    .box-medium {
        width: 100px;
        height: 100px;
    }
    
    .box-large {
        width: 150px;
        height: 150px;
    }
</style>
<script type="text/babel">
    const rootElement = document.getElementById('rootElement')
    function Box(props) {
        return (
            <div className="box box-small" style={{paddingLeft: 30}} {...props}></div>
        )
    }
    const styleElement = (
        <div>
            <Box style={{backgroundColor: 'red'}}>我是一个盒子</Box>
        </div>
    )
    ReactDOM.render(styleElement, rootElement)
</script>

函数组件默认有classNamestyle值,在使用时,重新给style赋了值,结果当然是覆盖了默认值。

那我们想不覆盖,只添加怎么办?

<div id="rootElement"></div>
<script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
    .box {
        border: 1px solid red;
    }
    
    .box-small {
        width: 50px;
        height: 50px;
    }
    
    .box-medium {
        width: 100px;
        height: 100px;
    }
    
    .box-large {
        width: 150px;
        height: 150px;
    }
</style>
<script type="text/babel">
    const rootElement = document.getElementById('rootElement')
    
    //重点看参数如何定义
    function Box({style, ...rest}) {
        return (
            <div className="box box-small" style={{paddingLeft: 30, ...style}} {...rest}></div>
        )
    }
    
    const styleElement = (
        <div>
            <Box style={{backgroundColor: 'red'}}>我是一个盒子</Box>
        </div>
    )
    ReactDOM.render(styleElement, rootElement)
</script>

这样既保留了默认属性值,又可以在此基础上添加新的值,这就要看你的组件想怎么设计了。

className可以同样这样处理:

<div id="rootElement"></div>
<script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
    .box {
        border: 1px solid red;
    }
    
    .box-small {
        width: 50px;
        height: 50px;
    }
    
    .box-medium {
        width: 100px;
        height: 100px;
    }
    
    .box-large {
        width: 150px;
        height: 150px;
    }
</style>
<script type="text/babel">
    const rootElement = document.getElementById('rootElement')
    
    //重点看参数如何定义,看默认className怎么写
    function Box({style, className, ...rest}) {
        return (
            <div className={`box ${className}`} style={{paddingLeft: 30, ...style}} {...rest}></div>
        )
    }
    
    const styleElement = (
        <div>
            <Box style={{backgroundColor: 'red'}} className="box-small">我是一个盒子</Box>
        </div>
    )
    ReactDOM.render(styleElement, rootElement)
</script>

这里唯一有个小小的缺陷,如果我们在使用Box组件时,没有给className赋值,会出现如图1的情况:

图1

如何解决呢?在定义函数组件参数的时候,给个默认值就好了。

//className默认值为空字符串
function Box({style, className = '', ...rest}) {
    return (
        <!--有人说这样还会多一个空格啊,完美主义者可以加个trim-->
        <div className={`box ${className}`.trim()} style={{paddingLeft: 30, ...style}} {...rest}>           </div>
    )
}

为啥style没有这个缺陷?开头说了style传的是对象哦,CSS天生键值对的形式恰恰又和对象相符,再加上spread操作符,可见react设计得周到和巧妙。

上一篇下一篇

猜你喜欢

热点阅读