It's really like useEffect but provides better support for cancellation and properly tracks promise. Rewriting this snippet with useEffect correctly would require quite a lot of code (although rewriting this snippet with useEffect incorrectly is possible with not a lot of code, but you don't want to write incorrect code). Which has to be repeated everywhere.
Again, this task is better solved by react-query or its alternatives. What I'm writing is not strictly web-site, but rather a web-interface on embedded device and web-server is not remote web-server but thing that works on the same device, so for now I decided not to use those libraries which made for slightly different use-cases.
I think I'd go about it using redux-thunk because I feel like render function is not a great place for complex async state changes and chcecking internal status of a promise is a bit low level, but you've built a nice, easy to use thing. If you published it some people might find it to be exactly what they need. Plus they might help you debug some corner cases.