Because at some point your function call is manipulating registers on the CPU. If we go even further, the CPU needs to load its next instructions and then the data required.
Point being, we abstract and encapsulate complexity and provide a simpler API around it. It’s the only feasible way to manage the inherent complexity.
React builds up a virtual description of UI. react-dom and react native take that description and synchronise it to the UI layer.
If you need to do something extra, that they don’t handle like managing a map widget (ie mapbox) in React that only has an imperative API, it sure would be nice to do that yourself.
You can build a UI without useEffect. You can hide messy implementation details inside a well tested component, and contain where useEffect is being used.
And, you can understand how useEffect works so that you can use it without it having a negative effect on you.