useMemo 记忆组件:
如果你学过vue,应该知道computed(计算属性)吧,没错,它就是和计算属性一样一样滴功能。但是其原理是:它会执行第一个函数并将函数执行的结果返回给你。那为什么它是调优的不二选则呢,因为它具有缓存功能,当页面其它组件或同一组件下其它数据发送变化时,组件会进行渲染,而它不会再渲染了。
这里以在同一组件下为例进行演示:
效果图:
应用场景:
当后端返回过来的数据(的)结构过于复杂时,可以把深层次的数据计算出来,再进行渲染,不然,你会疯掉的。
直接上案例吧:
1.在项目pubic目录下新建test.json文件
文件内容:
{
"data": {
"list": [
{
"id" :1,
"name" :"abc"
},
{
"id" :2,
"name" :"Abc"
},
{
"id" :3,
"name" :"jjAb"
},
{
"id" :4,
"name" :"udeca"
},
{
"id" :5,
"name" :"loUd"
},
{
"id" :6,
"name" :"lkMu"
},
{
"id" :7,
"name" :"wire"
},
{
"id" :8,
"name" :"ercty"
},
{
"id" :9,
"name" :"hJkgl"
},
{
"id" :10,
"name" :"sDfge"
},
{
"id" :11,
"name" :"hnegs"
},
{
"id" :12,
"name" :"NJuIk"
},
{
"id" :13,
"name" :"WyJnS"
},
{
"id" :14,
"name" :"PKenJK"
},
{
"id" :15,
"name" :"IjEngae"
},
{
"id" :16,
"name" :"Plejifsd"
},
{
"id" :17,
"name" :"IkPo"
},
{
"id" :18,
"name" :"Hgji"
},
{
"id" :19,
"name" :"BnMl"
},
{
"id" :20,
"name" :"Zxcv"
}
]
}
}
2.运行Demo08案例
代码如下:
import React, { useEffect, useState, useMemo } from 'react'
import axios from 'axios'
export default function Demo08() {
const [list, setlist] = useState([])
// useState:是具有缓存功能的
const [text, settext] = useState('')
const [name, setname] = useState('夏天')
useEffect(() => {
axios.get('/test2.json').then(res => {
// 成功的回调
console.log(res.data.data.list)
setlist(res.data.data.list)
}).catch(err => {
// 失败的回调
console.log('失败了呀')
})
return () => {
}
}, [])
// []:这里加list会导致一直发请求
// 原因:因为刚开始list为空,请求回来后会导致组件重新渲染,没问题
// 但是,它发现list数据变了,便会再次组件渲染,如此便形成了一直发请求
// 检索函数 --- 忽略大小写
const computedList = useMemo(() => list.filter(item => item.name.toUpperCase().includes(text.toUpperCase()))
, [list, text])
// useMemo:相当于Vue的计算属性,第一个参数():写自己的逻辑功能代码,这里以检索为例,第二个参数[],监听状态值的变化
return (
<div>
<div style={{ float: 'left', marginRight: '100px' }}>
{/* 功能一:查询 */}
{/* {text} */}
搜索框:<input type="text" value={text} onChange={(e) => settext(e.target.value)} />
<ul>
{
computedList.map(item =>
<li key={item.id}>{item.name}</li>
)
}
</ul>
</div>
<div >
{/* 功能二:修改名字 */}
<p>{name}</p>
<button onClick={() => {
name.includes('夏天') ? setname('冬天') : setname('夏天')
}}>点我换季节</button>
</div>
</div>
)
}
3.运行结果
自己执行yarn start就好了
总结:
useEffect函数的[ ]这里加list会导致一直发请求
原因:因为刚开始list为空,请求回来后会导致组件重新渲染,没问题。但是,它发现list数据变了,便会再次组件渲染,如此便形成了一直发请求。[ ]什么都不写就表示组件刚加载时只执行一次。
useMemo函数的[ ]这里必须要加参数,因为它可以检测状态值list与text是否发生变化,没变化则走缓存,反之,重新计算并渲染。