起因
在项目中一些渲染的元素不会频繁变动,所以使用了 useMemo。但在使用 useMemo 的时候忘了监听数据变化,就会导致 useMemo 中的渲染元素与外部的数据不一致。
示例
import { Button, Input } from 'antd'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import styles from './index.less'
export default () => {
const [num, setNum] = useState('333')
const renderText = useMemo(() => {
return <Button onClick={() => console.log(num)}>log</Button> // output 333
}, [])
const delayLog = useCallback(() => {
console.log(num) // output 333
}, [])
return (
<div className={styles.container}>
<Input value={num} onChange={e => setNum(e.target.value)} />
{renderText}
<Button onClick={delayLog}>delayLog</Button>
</div>
)
}
无论 Input 里面改成什么值,Button 的点击事件都只会返回 333。
解决方案
一种解决方案是在 useMemo 的监听数组里面添加 num
const renderText = useMemo(() => {
return <Button onClick={() => console.log(num)}>log</Button>
}, [num])
最后
另外,我发现在使用 ts-bus 的时候也有类似的问题。所以,在使用 useCallback 和 useMemo 的这种 API 的时候要格外注意。
网友评论