Imo [and I would say the general feeling] is that there is no real point using classes now. Hooks allow everything that classes can do (bar one very specific thing, error boundaries), they’re much less verbose and it’s generally a lot clearer what is happening when reading the code. (Edit: personally I dislike classes because I feel they obfuscate the code – a component is a function that takes input and produces output by running the JSX that’s defined, and by using classes I’m hiding what the input is, whereas with functions I can see instantly)
They’re orthogonal, and I think you mean Context, not hooks. React-redux uses hooks (and Context). Redux was probably overused in the past. It has specific usecases and you know when you need it: it shouldn’t generally be something you just immediately add to a project unless you’re very clear on the scope of the problem in advance. Context is extremely useful, and it can replace redux as an application state container completely for very simple things (things that want to rewrite the world when they change: authorisation and theming are two obvious cases). But if you use it in exactly the same way as react-redux (with large, complex state), you’d effectively just be rewriting react-redux without the performance optimisations, so it’s pointless.
Edit: re work being done on Redux, if you are adding Redux, I’d 100% recommend redux-toolkit, it takes away a lot of the boilerplate setup & includes common utilities that always need to get included (I think it’s the recommended way to start with it now; API is really nice anyway)
Fetch is fine most of the time. You often want some kind of application-specific wrapper over the top to deal with, amongst other things:
adding common headers on every call
adding things like Auth keys on every call
dealing with non-200 responses (fetch doesn’t error, you need to handle it yourself)
cancelling fetches (the AbortController need to be manually defined)
back off, timeouts etc
It is very often easy to do this, and it is often beneficial to write a wrapper that is specific to your application. Fetch was designed to be a low-level primitive that lets you build on it in this way. But Axios provides a lot of this stuff out of the box and is easy to use.