前言 最近在用ts+hooks这些新特性开发新的项目,前沿的东西开发的感觉是很丝滑美妙的,时时刻刻都在踩坑,无法自拔。 问题描述 目录结构大概是这样的 --RtDetail----Home------index.scss--
前言
最近在用ts+hooks这些新特性开发新的项目,前沿的东西开发的感觉是很丝滑美妙的,时时刻刻都在踩坑,无法自拔。
问题描述
目录结构大概是这样的
--RtDetail ----Home ------index.scss ------index.tsx ----Search ------index.scss ------index.tsx ----Detail ------index.scss ------index.tsx
然后我在Home组件中引入了Search和Detail组件,伪代码大概是这样的
/** * Home.tsx 伪代码 * 大概就是引入了Search和Detail,给Search传入一个回调,当Search的输入框改变时候,触发更改Home中的searchId */ ... let Home = () => { const [searchId, setSearchId] = useState(0) const handleSearchIdChange = (e) => { console.log('handleSearchChange 被创建了') setSearchId(e.target.value) } return ( <> <Search handleSearchId={handleSearchId}/> <Detail /> </> ) } export default Home /** Search.tsx 伪代码 */ ... let Search = (props: ISearchProps) => { const { handleSearchId } = props return ( <> <input onChange={(e) => {handleSearchId(e)}}/> </> ) } export default Search ... /** Detail.tsx */ ... let Detail = () => { console.log('Detail Component 被渲染了') return ( <span>test</span> ) } export default Detail ...
每次Search更改Home中seachId状态的时候,导致以下2个问题:
- 1.Detail都伴随着被重新创建了,从而造成了不必要的性能浪费
- 2.Home组件中,handleSearchId方法被重新创建
解决方案
memo+useCallback
对于问题1使用memo
/** 对Detail组件,包上一层memo,这是hooks提供的一个api */ ... let Detail = memo(() => { console.log('Detail Component 被渲染了') return ( <span>test</span> ) }) export default Detail
React.memo类似于React.PureComponent,能对props做浅比较,防止组件无效的重复渲染!
对于问题2使用useCallback
/** 改写Home.tsx */ ... let Home = () => { const [searchId, setSearchId] = useState(0) const handleSearchIdChange = (e) => { console.log('handleSearchChange 被创建了') setSearchId(e.target.value) } return ( <> <Search handleSearchId={handleSearchId}/> <Detail /> </> ) } export default Home
useCallback用于缓存inline函数,防止因属性更新时生成新的函数导致子组件重复渲染