一、组件的定义
1.class组件:继承React.Component,且需要创建render方法来返回元素。
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
2.函数组件
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
或者
const Welcome = (props) => {
return <h1>Hello, {props.name}</h1>;
}
二、state的定义、读取、修改方式
1. class组件
1) 定义:在constructor中定义(构造函数是唯一可以给 this.state 赋值的地方)
constructor(props) {
super(props);
this.state = {count: 0};
}
2) 通过this.state读取
<button>{this.state.count}</button>
3) 通过this.setState()修改数值 (它更新 state 变量总是合并它)
接收一个函数
this.setState((state, props) => ({
count: state.count + props.increment
}));
接收一个对象
this.setState({count: 2});
2. 函数组件
1)定义:用hook直接定义变量和方法
const [count, setCount] = useState(0);
2)直接读取
<p>You clicked {count} times</p>
3)通过setCount()方法修改数值 ( 它更新 state 变量总是替换它 ;已经有了 setCount 和 count 变量,所以我们不需要 this)
<button onClick={() => setCount(count + 1)}>
Click me
</button>
三、副作用操作的执行与生命周期
副作用操作:在 React 更新 DOM 之后运行一些额外的代码。
1. class组件(有生命周期)
由于我们希望在react更新dom以后执行操作,所以不会把副作用操作放在render函数中,而是放在生命周期 componentDidMount 和 componentDidUpdate 函数中。
但有时候,我们希望在组件加载和更新时执行同样的操作,所以需要在 componentDidMount 和 componentDidUpdate 中同时调用同一个方法。
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
2. 函数组件(无生命周期)
函数组件没有生命周期,其副作用操作使用useEffect执行。useEffect 会在每次渲染后都执行。
(生命周期函数是React.Component类的方法实现,函数式组件没有继承React.Component,所以没有生命周期函数。)
四、关于this
1.class组件:需要有this
1)组件传值获取方式:从this中取
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
2)事件的处理:需要绑定this
比如:用箭头函数绑定
class LoggingButton extends React.Component {
// 此语法确保 `handleClick` 内的 `this` 已被绑定。
// 注意: 这是 *实验性* 语法。
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
再比如:在构造函数内绑定
class LoggingButton extends React.Component {
constructor(props) {
super(props);
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
2. 函数组件:无this
1)组件传值获取方式:无this,从传入的参数中取
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
2)事件的处理:直接调用
function LoggingButton() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
五、关于实例
1. class组件
class组件有实例。
2. 函数组件
函数组件没有实例。由于没有实例,它不能使用ref属性。但可以在函数组件内部使用 ref 属性,只要它指向一个 DOM 元素或 class 组件。
六、使用选择
由于 class 组件 的使用需要了解 this 的工作方式, 还不能忘记绑定事件处理器,也没有稳定的语法提案,且不能很好的压缩,并且会使热重载出现不稳定的情况...
所以react开发人员建议使用函数组件,并推出hook来增强函数组件功能。
七、总结
1. 组件定义方式不同;
2. (因为组件定义方式不同)生命周期不同:class组件有,函数组件无;
3. (因为生命周期不同)副作用操作执行不同:class组件通过生命周期函数,函数组件用hook的useEffect;
4. state的定义、读取、修改方式不同:函数组件用hook的useState;
5. this:class组件有,函数组件无;
6. 实例:class组件有,函数组件无;
7. (因为实例不同)ref使用不同:class组件有,函数组件无;
8. 使用上: 官方推荐函数组件。