React hooks详解

发布于:2025-05-09 ⋅ 阅读:(4) ⋅ 点赞:(0)

一、为什么react需要引入hooks?

    react中hooks占有特别重要的地位。你可能会想,在react中有了类式组件,那么代码复用已经特别方便了,加上继承,配合typescript进行类型限制,那么整个代码就有点像Java风格了。为什么还是有特别多的人选择使用函数式组件呢,甚至还提出了专门处理函数式组件的hooks内置函数?
    React 引入 Hooks 并不是因为类组件 “不好”,而是为了提供一种更简洁、灵活的方式来处理组件的状态和副作用等功能,以满足不同的开发需求。类组件有其自身的优势,但也存在一些局限性,而 Hooks 则有效地解决了这些问题。
    对于类组件,类组件提供了诸如 componentDidMount等生命周期方法,在处理组件的初始化、更新和销毁时,能够清晰地分离和管理不同阶段的逻辑。可以通过继承来复用代码逻辑,减少重复代码。对于一些复杂的状态管理场景,类组件的 this.state 和 this.setState 可以方便地管理和更新状态,尤其是当状态之间存在依赖关系时,通过 setState 的回调函数可以确保状态更新的一致性。
    但是,类组件的语法相对繁琐,需要继承 React.Component,并且在方法中使用 this 来访问状态和方法,容易出现 this 指向问题,增加了代码的理解和维护成本。例如,为了在事件处理函数中正确使用 this,需要进行绑定操作(如 this.handleClick = this.handleClick.bind(this);)。类组件之间的逻辑复用通常通过高阶组件(HOC)或 Render Props 模式(具体来说指的是允许组件通过 props 接收一个函数并调用它来动态决定渲染内容)实现,但这些模式会增加组件的层级嵌套,导致组件树变得复杂,难以理解和调试,同时还可能引发命名冲突和性能问题。
    相比之下,Hooks 允许使用纯函数来编写组件,避免了类组件中的繁琐语法和 this 指向问题,使代码更加简洁、易读和易于维护。例如,使用 useState 钩子可以简单地在函数组件中添加状态,无需像类组件那样定义 this.state 和 this.setState。此外,Hooks 可以将相关的逻辑提取到自定义的 Hook 函数中,实现逻辑的复用,避免了高阶组件和 Render Props 模式带来的问题。例如,可以创建一个自定义的 useFetch Hook 来处理网络请求逻辑,多个组件可以复用这个 Hook,提高了代码的复用性和可维护性。通过 Hooks,可以将组件的逻辑按照功能拆分成多个小的函数,每个函数专注于一个特定的任务,使代码的结构更加清晰,便于理解和调试。最后,许多 React 库和工具(如 Redux、React Router 等)都开始提供基于 Hooks 的 API,使得在项目中使用这些库更加方便和直观,进一步提升了开发效率。

二、useState状态维护函数

    由于函数式组件本身相当于一个render函数,如果里面存在视图相关的值发生了变更,那么函数会重新执行,如果值频繁修改,那么这个函数会频繁执行,从而影响性能。于是为了维护函数式组件的状态值,Hooks中提供了专门的函数来维护——useState,首先给出useState的用法:

function App() {
   
  const [count, setCount] = useState(0);
  return <><button className='btn' onClick={
   () => setCount(count+1)}>{
   count}</button></>
}

    这里useState中的参数为左侧count的默认值,setCount作为唯一函数来修改count。但是这种方法依旧存在重复渲染的可能,举例如下:
在这里插入图片描述
    对这种情形进行解释,这里描述的是在函数式组件render内部修改了状态值,由于setState在异步代码中是同步执行的,因此setTimeout函数触发之后render会重新渲染,这时会重新执行一个setTimeout函数,最终导致组件会无限循环渲染。

三、useEffect副作用优化

    为了解决上面这种情况,出现了useEffect函数(可以使用多次),useEffect使用如下:
在这里插入图片描述
    useEffect接受两个参数,第一个是存在副作用的代码,第二个是依赖项,如果依赖项变化,那么会重复执行,如果是个空数组,那么只执行一次。
在这里插入图片描述
    下面以天气为例,展示怎么借助于useState和useEffect高效实现天气的动态切换,程序代码如下:

function App() {
   
  const [city, setCity] = useState("北京");
  const [weatherInfo, setWeatherInfo] = useState<WeatherItem[]>([]);

  useEffect(() => {
   
    axios.get(

网站公告

今日签到

点亮在社区的每一天
去签到