目录
[css in js解决方案](#css in js解决方案)
react组件分类
在React中,有三种主要类型的组件:
-
函数组件(Function Components):函数组件是使用函数定义的组件。它们接受输入参数(称为props),并返回一个React元素。函数组件没有自己的状态(state),也没有生命周期方法。它们通常用于描述无状态的、纯展示型的组件。
-
类组件(Class Components):类组件是使用ES6类语法定义的组件。它们是React组件的一种常用形式,可以包含状态(state)和生命周期方法。类组件必须扩展`React.Component`类,并实现`render()`方法,该方法返回一个React元素。
-
无状态函数组件(Stateless Functional Components):无状态函数组件是函数组件的一种特殊形式,它们没有内部状态(state)。这种组件类型的定义方式更简洁,只接收props并返回一个React元素。它们适用于纯展示型的简单组件。无状态函数组件在React 16.8版本之后引入的React Hooks之后变得更加常见和强大。
函数组件
函数组件(Function Components)是React中定义组件的一种方式,它是一种纯粹的JavaScript函数。函数组件接收props作为参数,并返回一个React元素来描述组件的输出。
函数组件是一种简单、轻量级的组件形式,适用于无状态的、只根据输入props进行渲染的组件。它们没有自己的内部状态(state)和生命周期方法,也不使用this关键字。相比于类组件,函数组件的语法更简洁,代码量更少。
创建函数组件的注意点
- 函数的首字母必须要大写(这是规定,让别人能够区分这是一个组件并不是一个普通函数)
- 函数中必须要返回React元素(JSX)
代码示例
javascript
// 创建一个函数组件
const App = props => (
<div className="app-root">
<h1>欢迎学习react!!!</h1>
<p>这是一个react函数组件</p>
</div>
)
// 导出这个组件
export default App;
函数组件的优点
-
简洁性:函数组件的定义方式更简单,代码量更少,适用于简单的UI渲染,没有复杂的状态和生命周期要处理。
-
性能优化:由于函数组件没有内部状态和生命周期方法,它们在某些情况下可以比类组件更轻量级、更高效。
-
易于测试:函数组件是纯函数,只依赖于输入的props并返回输出,没有副作用。这使得它们更容易编写和测试。
如果需要在组件中使用内部状态、生命周期方法或其他React特性,或者需要进行复杂的逻辑处理,那么应该使用类组件。但是在React 16.8及以后的版本,可以使用Hooks API在函数组件中使用状态和其他React功能,使函数组件变得更强大和灵活。
类组件
类组件指的是在React中使用ES6 class语法来定义的组件。类组件通过扩展React.Component类来创建,可以包含内部状态(state)、生命周期方法和其他功能。
在类组件中,通过构造函数(constructor)来初始化内部状态,通过生命周期方法(componentDidMount、componentDidUpdate、componentWillUnmount等)来进行特定的操作(例如发起网络请求、订阅/取消订阅事件等),通过渲染方法(render)来返回一个React元素来描述组件的输出。
创建类组件的注意点
- 我们创建的组件必须要继承React.Component这个父类
- 必须要有render方法
- render方法中必须要返回React元素(JSX)
注意:组件名的首字母必须大写。这是为了和普通的html标签区别开
代码示例
javascript
class Welcome extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
console.log("Component mounted.");
}
componentDidUpdate(prevProps, prevState) {
console.log("Component updated.");
}
componentWillUnmount() {
console.log("Component will unmount.");
}
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
在上面的示例中,Welcome
是一个类组件。它扩展了React.Component
类,并定义了构造函数(constructor)、生命周期方法(componentDidMount、componentDidUpdate和componentWillUnmount)和渲染方法(render)
-
构造函数:在构造函数中,我们通过
super(props)
调用父类的构造函数,然后初始化内部状态count
为0。 -
生命周期方法:在示例中,我们使用了几个常见的生命周期方法,包括
componentDidMount
、componentDidUpdate
和componentWillUnmount
。这些方法可用于在组件的不同生命周期阶段执行特定的操作,例如发起网络请求、订阅/取消订阅事件等。 -
渲染方法:
render
方法是必须的,它负责返回一个React元素来描述组件的输出。在示例中,render
方法返回一个包含问候语的标题元素(<h1>
)。
类组件的优点
-
灵活性:类组件可以管理内部状态、处理生命周期、引入各种方法和功能,更适合处理复杂的逻辑和交互。
-
扩展性:类组件可以通过继承和复用来构建更复杂的组件层次结构。
有状态和无状态组件的区别
有状态组件和无状态组件的主要区别在于是否管理内部状态和是否使用生命周期方法。
- 有状态组件(Stateful Components):
- 管理内部状态:有状态组件可以通过state属性来管理内部状态。这意味着它可以保存和改变数据,并通过setState方法触发UI更新。有状态组件通常用于存储和操作数据,以及处理用户交互。
- 使用生命周期方法:有状态组件可以使用生命周期方法来处理特定的阶段和事件。例如,componentDidMount在组件加载后调用,componentDidUpdate在组件更新后调用,componentWillUnmount在组件卸载前调用等。生命周期方法用于处理组件的生命周期和执行特定的操作,例如发起网络请求、订阅/取消订阅事件等。
- 无状态组件(Stateless Components):
- 不管理内部状态:无状态组件没有内部状态。它们只接收来自父组件的属性(props)作为输入,并根据这些属性渲染UI。无状态组件通常用于展示静态内容,没有自己的数据和状态。
- 不使用生命周期方法:无状态组件没有生命周期方法。它们不会在特定的阶段和事件上执行任何操作或处理逻辑。无状态组件仅关注UI的呈现,根据传入的属性(props)渲染并返回React元素。
无状态组件相对于有状态组件具有以下优点:
- 简洁:无状态组件没有内部状态和生命周期方法,代码相对简单,易于理解和维护。
- 性能优化:由于没有状态的变化,无状态组件可以更好地进行优化。React可以更轻松地对其进行渲染和重用,并且消耗更少的内存。
- 可复用性:无状态组件不依赖于特定的数据和状态,更易于复用,并且可以更容易地在组件层次结构中移动和组合。
总之,有状态组件适用于复杂的逻辑和交互,需要管理内部状态和使用生命周期方法。无状态组件适用于简单的UI呈现,不需要内部状态和生命周期方法。根据具体的应用场景和需求,可以选择合适的组件类型来开发。
组件样式
行内样式
- 想给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现。
- React推荐我们使用行内样式,因为React觉得每一个组件都是一个独立的整体
javascript
{ /* 注意这里的两个花括号,第一个表示我们在要JSX里插入JS了,第二个是对象的花括号 */
}
<p style={{color:'#c00', fontSize:'14px'}}>这是一个react函数组件</p>
行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方。例如
render 函数里、组件原型上、外链 js 文件中
外链样式
- 将css样式写在一个单独的css文件中,然后在通过 import 导入
javascript
/* App.css */
.title {
background: #ff0;
}
javascript
// App.js
import "./App.css";
<div className="title">欢迎学习React!</div>
css in js解决方案
- css in js 解决方案其实就是将css样式写在js****文件里面的一种技术
- 现在比较热门的 css in js 解决方案的库有以下三种
- aphrodite:目前github上有4k的star
- radium:目前github上有6k的star
- styled-components:目前github上有17k多的stat
- 使用方式,下面介绍 aphrodite 的使用方式。
- 下载aphrodite
javascript
npm install --save aphrodite
- 在组件中使用
javascript
import { StyleSheet, css } from 'aphrodite';
// 创建一个函数组件
const App = props => (
<div>
<div className={css(styles.red)}>
这里的背景色是红色的
</div>
<div className={css(styles.hover)}>
鼠标移上变成红色背景
</div>
<div className={css(styles.small)}>
当浏览器的宽度小于等于600px的时候这里是红色的
</div>
<div className={css(styles.red, styles.blue)}>
这里的背景色是蓝色的
</div>
<div className={css(styles.blue, styles.small)}>
当浏览器的宽度小于等于600px的时候这里是红色的,否则就是蓝色的
</div>
</div>
)
// 定义css样式
const styles = StyleSheet.create({
red: {
backgroundColor: 'red'
},
blue: {
backgroundColor: 'blue'
},
hover: {
':hover': {
backgroundColor: 'red'
}
},
small: {
'@media (max-width: 600px)': {
backgroundColor: 'red',
}
}
});
// 导出这个组件
export default App;
- radium使用
javascript
import Radium from 'radium';
// 创建一个函数组件
const App = props => (
<div>
<div style={ styles.red }>
这里的背景色是红色的
</div>
</div>
)
// 定义css样式
const styles = {
red: {
"color": "#c00"
}
}
export default Radium(App)
- css module的使用
将 css 的文件名改为: App.module.css , 这样做会为你这个 css 文件下所有的 id 名或者 class 名添加一个随机的后缀名。这样就可以防止和其它的文件冲突了
使用
javascript
// App.js
import { Component } from 'react';
import style from "./App.module.css"
class App extends Component {
render() {
return (
<div id="root" className={ style['app-root'] }>
App
</div>
)
}
}
export default App;
全局处理
javascript
:global('#root') {
background: #eee;
}