React Hooks


react hooks 是react16.8的新特性,它允许我们在不用编写class(函数组件)的情况下使用state等其他react特性

useState

useState是需要学习的第一个hook,它传入一个参数作为初始值,返回一个数组,分别为state名和操作state的方法
const [state,setState]=useState(0)
上边例子使用useState hook,创建name为state(是可选的-命名)的state,第二个参数为操作该state的方法,命名都是可选的,即数组的解构操作.与this.statethis.setState,为什么不称为createState是由于只有第一次创建时才是真正的创建,之后仅仅是使用

import React,{useState,useEffect} from 'react';
function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <h1>currentValue:{count}</h1>
      <button onClick={()=>setCount(count+1)}>点击加1</button>
    </div>
  );
}

需要注意的是hook只能在函数顶层使用,不要在循环、判断等中执行hook,原因在于hook的执行机制是顺序执行的,当其中一环丢失的时候可能会造成后边的hook出错,不知道state是什么.可以使用eslint-plugin-react-hooks官方推荐的ESLint 插件来强制执行规则.

useEffect

在React中我们常常会做数据获取、订阅内容等操作,我们将这些操作称为“副作用”,useEffect的作用就是执行这些“副作用”,当每次渲染完成后,会执行useEffect hook.类似与class 中类似componentDidMountcomponentWillUnMountcomponentDidUpdate的作用,为上边例子添加更改文档title的作用,会在每次渲染后执行

useEffect可以像useState一样调用多次,将状态逻辑分割开

function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    // 类似与componentDidUpdate componentDidMount
    document.title = `You clicked ${count} times`;
  })
  return (
    <div className="App">
      <h1>currentValue:{count}</h1>
      <button onClick={()=>setCount(count+1)}>点击加1</button>
    </div>
  );
}

但是如果我们有时需要在卸载组件取消一些订阅、监听的取消,我们需要在class中的componentWillUnMount生命周期中清除这些内容,useEffect做到了这点,由于添加和清除一般就是绑定在一起,React Hook将他们结合到了一起,在useEffectreturn一个function作为组件卸载时的effect

import React,{useState,useEffect} from 'react';
import './App.css';
function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    // 使用浏览器的 API 更新页面标题
    document.title = `You clicked ${count} times`;
    return ()=>{
      console.log('exit!')
    }
  })
  return (
    <div className="App">
      <h1>currentValue:{count}</h1>
      <button onClick={()=>setCount(count+1)}>点击加1</button>
    </div>
  );
}
为什么要在每次渲染后都要执行一次effect

useEffect会在每次渲染后都要执行一次,主要原因在于可能减少React出Bug的可能性,假设现在有一以下业务场景

  • 在componentDidMount中订阅内容
  • 在componentWillUnMount中取消订阅

似乎没有问题,但是如果这是更新了props订阅内容是不会更新的,这时候必须添加componentDidUpdate中重新获取内容,但是依靠useEffect的机制就非常简单了,直接订阅内容,在return中取消订阅,由于每次渲染都会重新执行的原因,不用考虑这么多问题,但是也会带来一个问题,就是性能问题,毕竟站在用户层面更多的还是考虑性能问题,像useEffect这样每次挂载卸载都会执行势必会存在一些问题,这个时候可以用过跳过effect进行性能优化.

跳过effect进行性能优化

在class中我们可以在componentDidUpdate中通过判断是否一致进行操作,在useEffect怎么办?通过指定useEffect的第二个参数,可以控制其执行,传入数组,当数组中的变量更改时执行,也可以指定为空数组,那么该effect只会执行一次.

  useEffect(() => {
    // 使用浏览器的 API 更新页面标题
    document.title = `You clicked ${count} times`;
    return ()=>{
      console.log('exit!')
    }
  },[count]);//只有count发生更改时才会触发该effect,如果为空数组,那么页面title一直为You clicked 0 times

另外可以使用React.memo进行性能优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值