Hooks的使用
类组件和函数组件的区别
类组件和hooks是两个概念,hooks只是一个工具集,用来增强函数组件的功能。真正对比的是类组件和函数组件的差异。
代码风格上的差异
类组件中有:
- 是一个class类,需要继承
- 可以直接定义内部的state状态
- 组件内有生命周期钩子
-
应用数据props不同
两类组件之间最大的区别,用https://overreacted.io/zh-hans/how-are-function-components-different-from-classes/表示“函数式组件捕获了渲染所用的值(props),props会在函数组件中形成闭包”
网站所用的实例代码:函数组件
function ProfilePage(props) {
const showMessage = () => {
alert('Followed ' + props.user);
};
const handleClick = () => {
setTimeout(showMessage, 3000);
};
return (
<button onClick={handleClick}>Follow</button>
);
}
类组件
```javascript class ProfilePage extends React.Component { showMessage = () => { alert(‘Followed ‘ + this.props.user); };
handleClick = () => { setTimeout(this.showMessage, 3000); };
render() { return ; } }
<a name="CwDa3"></a>
### 对比不同
用类组件和函数组件实现同样的关注逻辑,两种组件都会接受props.user的属性,点击关注按钮3秒后会弹出一条信息。如果一开始传入的是{user: "帅哥"},然后在3秒内切换prop的值变化成{user: "美女"}。类组件和函数组件的结果会不同:
```javascript
// 函数组件会打印
'关注帅哥'
// 类组件会打印
'关注美女'
线上代码演示:https://codesandbox.io/s/duibileizujianhehanshuzujian-uh8yf
在类组件中props是不变的,但是this永远是变化的。当有数据更新,props和state会同步更新。
解决类props的实时更新
第一种办法,在调用props之前读取this.props,然后将他们显示的传递到异步回调
class ProfilePage extends React.Component {
showMessage = (user) => {
alert('关注'+ user)
};
handleClick = ()=>{
const {user} = this.props;
setTimeout(()=> this.showMessage(user), 3000)
};
return() {
return <button onClick={this.handleClick}>关注</button>
}
}
这个方法生效,但是会让代码变的冗长,难以维护,容易出错。
另一种方法:把事件写在render函数中
class ProfilePage extends React.Component {
render() {
const props = this.props;
const showMessage = () => {
alert('成功关注 ' + props.user);
};
const handleClick = () => {
setTimeout(showMessage, 3000);
};
return <button onClick={handleClick}>关注</button>;
}
}
这个方法其实函数组件的原理,props变化之后,组件虽然重新渲染了,但是老的props通过闭包保存了下来,然后被打印出来。
为什么要使用函数组件+hooks
对比类组件的缺点,函数组件+hooks有以下优点:
- 函数组件写法更轻量灵活
- 在函数组件中,我们不需要去继承一个class对象,不需要记忆那些生命周期,不需要固定的把数据定义在state中。
- 函数作为js中的一等公民,函数式编程方式可以让我们可以更加灵活的去组织代码。
- 类组件存在缺陷
- 在React中,如果我们定义一个方法,我们必须使用bind或者箭头函数去约束这个方法的this的作用域。
- 如果需要一个只跟着视图触发事件时的数据显示,不能直接使用props或state
- hooks更符合react的基本理念
- 在一次渲染中,props和state是保持不变
但是hooks并不能完全替代类组件,hooks很多方法,用来增强函数组件的功能。如useState/useEffect/useRef/useContext/useMemo/useReducer