I have a component:
export const Filters: FC = observer(() => (
<div className={`filters ${viewModel.isDragged ? 'filters--dragged' : ''} ${!viewModel.isOpened ? 'filters--collapsed' : ''}`}
style={viewModel.position}>
<FiltersHeader/>
<FiltersBody/>
</div>
));
This component is decorated with observer
from mobx-react-lite
. Field position
is decorated with @observable
decorator from mobx
package. position
is consist of field left: number
and top: number
.
I want to drag this component. And to achieve it I reinisialize position
when user triggers mousemove
.
The problem is <FiltersHeader/>
and <FiltersBody/>
not small components, it takes a while to render them. And each time I change viewModel.position
React rerender entire tree. Not only FiltersHeader and FiltersBody, also their children and their children, etc.
Why does React do that? I mean, FiltersHeader has no properties. React should not rerender the component again if its properties did not change. Or should it?
This code works the same
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>
);
}
As other commenter said, React does not apply optimizations by default, so every child component will rerender (even if it has no props) when parent component does.
You can wrap them in React.memo
or actually wrap in observer
too, because it also applies memo
automatically.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.