微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React 重新渲染组件的完整树

如何解决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: numbertop: 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 举报,一经查实,本站将立刻删除。