什么是hooks?
hook是React 16.8的新增特性,它可以让你在不编写class的情况下使用state及其他react特性。
使用hooks的函数组件可以简化代码、不用维护复杂的生命周期,也不用担心this指向的问题。
hooks的特点
优点
- 可以让你使用函数组件的方式,运用类组件以及 react 其他的一些特性,比如管理状态、生命周期钩子等
- 代码可读性更强,通过 React Hooks 可以将功能代码聚合,方便阅读维护。
- 减少了很多模板代码,特别是小组件写起来更加省事,人们更愿意去拆分组件。而组件粒度越细,被复用的可能性越大。所以,hooks也在不知不觉中改变人们的开发习惯,提高项目的组件复用率
- 没有了 this 指向问题
注意事项
- 需要熟悉纯函数、副作用、柯里化、高阶函数等概念
- 遵循函数“单一职责”,需要关注依赖项和调用顺序,如useEffect等hooks的第二个参数
- 响应式的 useEffect ,必须清楚代码中 useEffect 和 useCallbac k等api的第二个参数“依赖项数组”的改变时机,并且掌握上下文的 useEffect 的触发时机。当逻辑较复杂的时候, useEffect 触发的次数,可能会被你预想的多
- 更偏向于用 hooks 来写组件,在复杂业务中,更倾向于用 class Component 或者两者结合的方式
1. useState
调用useState可以在函数组件中定义一些内部的state,React在重复渲染时会保留这个state,它类似 class 组件的state, 案例中的setState 和类组件中的 this.setState不同,它不会把新的 state 和旧的 state 进行合并。
const Btn = (props) => {
const data={
count:0,
name:"张三"
}
// useState的参数是初始data,这里不一定要是一个对象,也可以是一个基本数据类型的值,
// setState和class中的this.setState不同,它是修改前面state的一个方法
const [state,setState]=useState(data);
const changeCount=()=>{
let {count}=state;
// 注意:这里需要先解构state,以免修改了其他不需要修改的值
setState({...state,count:count+1})
}
const changeName=()=>{
setState({...state,name:'李四'})
}
return (
<>
<span className="mr10" >{state.count}</span>
<span className="mr10" >{state.name}</span>
<Button className="mr10" type="primary" onClick={changeCount}>加一</Button>
<Button className="mr10" type="primary" onClick={changeName}>修改名字</Button>
</>
)
}
2. useEffect
提示
1.数据获取,设置订阅,启动定时器以及手动更改React组件中的DOM都属于副作用
2.useEffect 在dom渲染后执行
简介:
- effect 可以在函数组件中执行副作用操作
- useEffect 可以看做是 componentDidMount , componentDIdUpdate , componentWillUnmounent三个函数的组合。
- useEffect 可以传两个参数
(1) 只传一个参数时,页面挂载后和页面更新时都会执行,
(2) 当传第二个参数 [] 空数组时只会在页面挂载执行一次,[] 空数组代表所有的state的值都不监测,相当于componentDidMount
(3) 当数组中有值时会监测相应的值,当依赖的值发生变化后,useEffect会执行
4.通过return ()=>{}的方式可以解绑生命周期,相当于componentWillUnmounent。useEffect 在同一个钩子中实现绑定与解绑使状态管理更加方便、代码更简洁。
语法说明:
// 只传一个参数
useEffect(()=>{
// 在此可以执行任何带副作用操作
})
// 传入两个参数,第二个参数为空数组
useEffect(()=>{
// 在此可以执行任何带副作用操作
},[])
// 传入两个参数,第二个参数中有值时
// 当count发生变化后,useEffect会执行
useEffect(()=>{
// 在此可以执行任何带副作用操作
},[count])
3. useRef
简介:
- useRef() 比 ref 属性更有用,可以保存任何可变值(dom 元素或组件实例),类似于 class 中使用实例字段的方式。
注意:
1.当 ref 对象内容发生改变时,useRef()并不会通知你,变更.current属性不会引发组件的重新渲染(示例1)
2.useRef()只能用来访问 class 类组件,函数式组件没有实例!
示例1
const Btn = (props) => {
const data={
count:0,
name:"张三"
}
const [state,setState]=useState(data);
const nameRef=useRef(null)
const changeName=()=>{
nameRef.current.value='李四'
console.log('--->nameRef',nameRef.current.value)//页面不会更改
}
return (
<>
<span className="mr10" ref={nameRef}>{state.name}</span>
<Button className="mr10" type="primary" onClick={changeName}>修改名字</Button>
</>
)
}