如何解决React 重新渲染组件的完整树
export const Filters: FC = observer(() => (
<div className={`filters ${viewmodel.isDragged ? 'filters--dragged' : ''} ${!viewmodel.isOpened ? 'filters--collapsed' : ''}`}
style={viewmodel.position}>
<FiltersHeader/>
<FiltersBody/>
</div>
));
这个组件用 observer
中的 mobx-react-lite
修饰。字段 position
用 @observable
包中的 mobx
装饰器装饰。 position
由字段 left: number
和 top: number
组成。
我想拖动这个组件。为了实现它,我在用户触发 position
时重新初始化 mousemove
。
问题在于 <FiltersHeader/>
和 <FiltersBody/>
不是小组件,渲染它们需要一段时间。每次我更改 viewmodel.position
React 时都会重新渲染整个树。不仅是FiltersHeader和FiltersBody,还有他们的孩子和他们的孩子等等。
为什么 React 会这样做?我的意思是, FiltersHeader 没有属性。如果组件的属性没有改变,React 不应再次重新渲染组件。还是应该这样?
这段代码的作用是一样的
export const Filters: FC = () => {
const [position,setPosition] = useState(viewmodel.position);
useEffect(() => {
reaction(() => viewmodel.position,value => setPosition(value));
},[]);
return (
<div className={`filters ${viewmodel.isDragged ? 'filters--dragged' : ''} ${!viewmodel.isOpened ? 'filters--collapsed' : ''}`}
style={position}>
<FiltersHeader/>
<FiltersBody/>
</div>
);
}
解决方法
正如其他评论者所说,React 默认不应用优化,所以当父组件重新渲染时,每个子组件都会重新渲染(即使它没有道具)。
您可以将它们包裹在 React.memo
中或实际上也包裹在 observer
中,因为它也会自动应用 memo
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。