1、类组件有生命周期,函数组件没有
2、类组件需要继承 Class,函数组件不需要
3、类组件可以获取实例化的 this,并且基于 this 做各种操作,函数组件不行
4、类组件内部可以定义并维护 state, 函数组件都称为无状态了,那肯定不行。
函数式组件捕获了渲染时所使用的值,这是两类组件最大的不同
import React from "react";
import FCComponent from "./fc-component";
import ClassComponent from "./class-component";
export default class LearnComponentDiff extends React.Component {
state = {
user: "王凯",
};
render() {
return (
<>
欢迎关注 {this.state.user}!
(函数组件)
(类组件)
你能看出两者的不同吗
>
);
}
}
import React from 'react';
class ClassComponent extends React.Component {
showMessage = () => {
alert('选择的 ' + this.props.user);
}
handleClick = () => {
setTimeout(this.showMessage, 3000);
};
render() {
return ;
}
}
export default ClassComponent;
点击页面后我们发现 初始化的props改变了! user 是通过 props 下发的,props不可改变,那么造成数据改变的原因就一定是 this 指向改变了。
真正的原因也确实如此,虽然props不可改变,但是this是可变的,this.props 的每次调用都会去获取最新的 this 值,这也是React保证数据实时性的重要手段。
那么就很清晰了,当showMessage最终执行时,此时的 this 绑定的是 张三对应的上下文,所以输出为 ‘已关注 张三’
import React from 'react';
function FCComponent(props) {
const showMessage = () => {
alert('已关注 ' + props.user);
}
const handleClick = () => {
setTimeout(showMessage, 3000);
};
return (
);
}
export default FCComponent;
最终的输出值明显为 ‘选择的 王凯’,props 会在函数执行的瞬间就被捕获,而 props 本身又是不可变值,所以我们可以确保从当前开始读取到的 props 都是最初捕获到的。当父组件传入新的 props 尝试重新渲染函数时,本质是基于新的 props 入参重新调用了一次函数,并不会影响上一次调用。这就是 Dan 所说的函数式组件捕获了渲染所使用的值,并且我们还能进一步意识到:函数组件真正将数据和渲染紧紧的绑定到一起了
注意:
很多人认为在函数组件中延迟输出的 state 是调用时的 state,而不是最新的 state 是一个Bug,恰恰相反,这是一个函数式组件的特性,是真正践行了React设计理念的正确方式。
当然Hooks也给出了获取最新的props和state的方法,就是 useRef,详细用法在我们的课程已经有所介绍,同学们可以自行回顾一下
大家可以看一下React 团队核心成员和 Redux 作者 Dan的这边文章。进阶理解这部分也借鉴了Dan大佬的这篇文章
函数式组件与类组件有何不同?
当你不想在构建环境中配置有关 JSX 编译时,不在 React 中使用 JSX 会更加方便。每个 JSX 元素只是调用 React.createElement(component, props, ...children) 的语法糖。因此,使用 JSX 可以完成的任何事情都可以通过纯 JavaScript 完成
React最终编译打包后都在一个html页面中,如果在两个组件中取一样类名分别引用在自身,那么后者会覆盖前者。默认情况下,只要导入了组件,不管组件有没有显示在页面中,组件的样式就会生效。也就是说并没有自己的局部作用域
1、手动处理 (起不同的类名,但是项目一大就会导致类名很乱,不利于团队协作)
2、CSS IN JS : 以js的方式来处理css(推荐)
CSS IN JS是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题。
CSS IN JS 的具体实现有 50 多种,比如:React常用(CSS Modules、styled-components)、 Vue常用(