Single JS threads restricts your business logic a lot. If you start doing any serious work in JS, your app will suffer greatly.
Regarding native components, the result is that views just don't look native, animations are not native (even down to different timing functions), view behaviors are different (the RN button fade out on tap is different than UIButton, etc).
On top of that, since the JS thread is responsible for UI rendering and business logic, if your JS thread is busy, UI is "stuck", being unable to rerender until the JS thread is freed.
All these issues pile up to create a bad result at the end. Add to that the human element (not always being mindful of performance implications), and it is worse. But, definitely, the ceiling is very low at how much you can achieve.
I say all these things from experience; I work next to a team of dedicated RN developers at my company. In many cases, the need to drop to native is apparent and necessary, which makes the point of RN moot.
Certainly, RN is better than Cordova; no doubt about that. But it's just not as good as many people want to fool themselves at believing.