假设我有一个简单的功能组件,它根据过滤器字段呈现许多其他功能组件。 HomeView
是父功能组件,它使用状态来处理 DomainCard
(子功能组件)过滤:
const HomeView = props => {
// domains
const domains = useSelector(state => state.domains)
const [nameFilter, setNameFilter] = useState('')
const goToDomainDetailView = id => {
history.push(config.urls.domainLocal.replace(':id', id))
}
return (
<div>
<div style={{ marginTop: '2rem', marginBottom: '2rem' }}>
<Input
icon='search'
placeholder='Search domain'
onChange={(e, { value }) => setNameFilter(value)}
/>
</div>
<div>
{domains.data
.filter(domain => !nameFilter || domain.name.toLowerCase().includes(nameFilter.toLowerCase()))
.map((domain, idx) => (
<div key={idx}>
<DomainCard
fluid
raised
onClick={goToDomainDetailView}
id={domain.id}
title={domain.name}
image={DomainAutomotiveImage}
/>
</div>
))}
</div>
</Container>
</div>
)
}
现在这里发生的事情是,在过滤时,已经显示的组件( DomainCard
)会重新渲染,即使是内存它们。那是因为HomeView
组件本身由于其状态变化而重新呈现,并且作为功能组件,goToDomainDetailView
函数被重新定义,并且与之前的提交相比发生了变化。
所以我唯一想到的就是定义 goToDomainDetailView
组件外部:
const goToDomainDetailView = id => {
history.push(config.urls.domainLocal.replace(':id', id))
}
const HomeView = props => {
// domains
const domains = useSelector(state => state.domains)
const [nameFilter, setNameFilter] = useState('')
return (
<div>
<div style={{ marginTop: '2rem', marginBottom: '2rem' }}>
<Input
icon='search'
placeholder='Search domain'
onChange={(e, { value }) => setNameFilter(value)}
/>
</div>
<div>
{domains.data
.filter(domain => !nameFilter || domain.name.toLowerCase().includes(nameFilter.toLowerCase()))
.map((domain, idx) => (
<div key={idx}>
<DomainCard
fluid
raised
onClick={goToDomainDetailView}
id={domain.id}
title={domain.name}
image={DomainAutomotiveImage}
/>
</div>
))}
</div>
</Container>
</div>
)
}
现在,在这种情况下,这个东西可以工作了。
但它有效,因为 goToDomainDetailView
例如,函数不依赖于组件 props 或 Redux 调度函数。如果是这种情况,我根本无法将函数移到外面,而我想象的避免重新渲染的唯一其他方法是转换 HomeView
Component 类中的组件,因此 goToDomainDetailView
函数可以定义为类方法,但在重新渲染时不会改变。
所以问题是:
- 我的假设正确吗?
- 您如何处理这种常见情况?
- 在您看来,这是使用带有状态的嵌套功能组件并避免重新渲染所有功能子组件的正确方法(例如使用
React.memo
的第二个参数并避免重新渲染,如果只有处理程序函数 ref变化?)。
最佳答案
您可以使用 useCallback()
Hook 来内存回调:
...
const somePropDependantCallback = useCallback(
id => console.log(id, someProp),
[ someProp ]
);
关于reactjs - 将事件处理程序传递给嵌套功能组件时如何避免重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58394232/