React Hooks使用经验以及技巧

React Hooks的一些使用经验以及技巧

最近一段时间都在使用React Hooks,简单记录下使用技巧,比较常用的hook有:useState、useEffect、useRef、useMemo、useCallback...

hook通用规则:

  1. 只在 React 函数中调用 Hook。
  2. 不要在循环、条件或嵌套函数中调用 Hook。

一.useState

javascript 复制代码
// name 和 setName 名称自己定义
const [name,setName] = useState('')

// 更改 name 为 'aquan'
const onClick = () = >{
	setName('aquan')
}

useState是用来存储状态的hook,其中 name 表示变量名称,setName表示改变state的函数,useState接受一个参数,这个参数为 state 的初始化值。

用法是比较简单的,但是需要注意的点有

  1. 在 setName 后立马打印 name 是获取不到最新的值的,因为 useState 是异步的,如果想要获取新的值之后做什么操作,可以参考下面的 useEffect。

  2. 调用多次 setName 只会以最后一次为准,例如:

javascript 复制代码
const onClick = () = >{
	setName('aquan')
	setName('quan')
	// 最后 name 的值为 quan
}

如果你的值基于上一次更新,setName 可以接受一个函数,参数会有上一次更新的值

javascript 复制代码
const onClick = () = >{
	setName('aquan')
	setName((val)=>val+'-demo')
	// 最后 name 的值为 aquan-demo
}

3.每次调用 setName 会导致组件重新更新一次,为了优化体验,有时候尽量把多个setState改成一个,避免多次渲染

javascript 复制代码
const onClick = () = >{
	setName('aquan')
	setAge(18)
	// 会导致组件刷新两次,在setName完成后刷新一次,在setAge完成后又刷新一次
	// 可以改为
	setData({name:'aquan',age:18})
}

二.useEffect

useEffect可以让你在一些情况下,执行自己的想添加的操作,例如:监听state变化时,组件加载完成时,组件销毁时。

useEffect接受两个参数,第一个参数为函数,可以传入用户想要执行的操作,第二个参数为监听项,但第二个参数变化时,会执行用户传入的函数

1.监听state变化时(useEffect第二个参数有值,当然因为是数组也可以传多个state监听)

javascript 复制代码
useEffect(()=>{
	// state初始化的时候也会进来一次
	console.log(name)
},[name])

这个一般用于,在某个值变化的时候执行自己的操作,例如:有一个搜索功能,有好几个下拉框,在用户选择下拉框的时候,你希望能请求一下数据查询

javascript 复制代码
const [query,setQuery] = useState({})

const handleChangeSelect = () => {
	setQuery({level:1})
	// 如果你有多个参数,建议改为
	setQuery((val)=>{...val,level:1})
	// 或
	setQuery({...query,level:1})
	// 避免更改覆盖了之前query的除开level其他值
}

const getData = (params) => {
	// 根据参数请求接口重新查询数据
}

useEffect(()=>{
	getData(query)
},[query])

2.组件加载完成时(第二个参数为空数组)

javascript 复制代码
useEffect(()=>{
  // 组件加载完成时,一般用于组件刚进来获取数据,调用接口
  getData()
},[])

3.组件被销毁时(return了一个函数)

javascript 复制代码
useEffect(()=>{
  return  () => {
  // 组件被销毁时调用 一般用于清除定时器或者销毁前的一些操作
   console.log('组件销毁')
  }
},[])

三.useRef

useRef一般用于获取dom元素

javascript 复制代码
const testRef = useRef()

// dom元素
<div ref={testRef} id='test'>测试文本</div>

// 此时testRef 等于,可以直接拿到dom元素
testRef.current  =  document.getElementById('test')

有时候也可以用作变量存储,或者存定时器,用名称.current去赋值和获取

javascript 复制代码
const timerRef = useRef()

useEffect(()=>{
// 组件加载完成,设置定时器
  timerRef.current = setInterval(()=>{
  	console.log('时间正在流逝')
  },[1000])
	return ()=>{
	//组件销毁时清除定时器
	  clearInterval(timer.current);
	}
},[])

注意: 使用useRef当做变量存储的话,变量如果发生更新,组件不会重新渲染,所以一般还是用useState存储状态,除非个别情况下用第三方插件可能导致useState拿不到新更新的值。

四.useMemo

useMemo涉及到性能优化这块了,可以让一些变量避免重复声明,同样接受两个参数,第一个是回调函数,第二个是数组

javascript 复制代码
const demo = () => {
  const [count, setCount] = useState(0);
  const [status, setStatus] = useState(0);

  // 每次组件更新都会重新声明一次,点击改变状态也会导致重新声明
  const isBigNum =  count > 1
  // 使用useMemo可以让变量只在加载完成时更新,以及监听对象更新时重新声明
  const isBigNum = useMemo(()=> count > 1,[count])

  const handleOnClick = ()=>{
  	  setCount(val=>val+1)
  }
  
  const handleOnChangeStatus = ()=>{
  	  setStatus(!status)
  }

  return (<div>
	<div onClick={handleOnClick}> 点我+1 </div>
	<div onClick={handleOnChangeStatus}> 点我改变状态 </div>
    </div>);
};

export default demo;
相关推荐
别拿曾经看以后~1 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
川石课堂软件测试1 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai2 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
problc2 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter