Sobre a afirmação que tudo é funcional, uma mentira, o que se usa mesmo é um monte de programação procedural, com alguma influência ou outra de FP e OO.

O React principalmente tem uma propaganda muito forte em cima de FP (muito por conta do Redux), mas a única coisa que ele realmente tenta aplicar é a imutabilidade que é algo presente mesmo em outros paradigmas, inclusive por ser um requisito para desenhar coisas que vão funcionar com programação concorrente. Inclusive os poucos padrões funcionais utilizados como os HOCs foram substituídos pelos hooks.

Já faz tempo que um componente React não é uma função pura (que é no que o paradigma funcional é baseado), fora que todo o ponto de se usar FP é evitar efeitos colaterais, sem isso não dá para dizer que você está usando FP, e hooks são exatamente uma forma de causar efeitos colaterais sincronizados com o sistema de reatividade do React. Isso quando o caso não piora e o componente está cheio de requisições que é o. cúmulo de causar efeitos colaterais.

Só que isso tudo não torna OO ou até mesmo a FP inviáveis. Na verdade, elas podem trazer grandes benefícios para o seu código, é só que tem muita gente que só repete as coisas que nem papagaio sem entender de verdade o que está fazendo.

Você pode usar FP para estruturar um reducer de forma mais elegante usando o TS match e alguma lib que tenha um utilitário de composição tipo o pipe do Ramda. Você pode utilizar monadas como Result e Optional e criar componentes que recebem esses valores como prop e lidar com erros de forma declarativa, pode usar currying para generalizar certos algoritmos por exemplo event handlers, ou funções que vão num useReducer.

Você pode usar OO para estruturar a sua aplicação seguindo alguma arquitetura como a hexagonal por exemplo, já que o poliformfismo da OO torna bem simples montar sua aplicação de forma plug'n play.

Outra coisa é que varios dos seus arquivos de utilidades que são módulos do JS, onde você cria funções para lidar com um tipo ou conjunto de dados, e acaba repetindo o parâmetro que recebe esse dado em todas as funções (uma abordagem bem procedural eu diria), podia muito bem ser melhorado com um pouco de encapsulamento e tornar todas essas funções de um ou mais parâmetros em métodos de 0 parâmetros dentro de um objeto que recebe o valor comum delas no construtor, de bônus vc ainda faz a computação ser lazy com essa abordagem.

Surgiu um componente que precisa de flexibilidade e pode precisar fazer a mesma coisa de formas diferentes, e você tem varias dessas coisas? Uma interface para aplicar o polimorfismo e agregar elas num ponto só poderia ser uma ótima solução.

Enfim, tem várias outras situações onde você pode aplicar ambos os paradigmas, desde que você conheça bem os princípios, quando surgir uma oportunidade onde eles fazem sentido, você vai saber quando utilizar, e elas podem ser mais comuns do que você imagina.

... fora que todo o ponto de se usar FP é evitar efeitos colaterais, sem isso não dá para dizer que você está usando FP, ...

Estava olhando Elm e os relatos são do tipo: faça o deploy e vá dormir, anos rodando sem problemas, os incidentes foram em JS, Scala, downtime, etc..

A linguagem é simples e o compilador tem mensagens de erro bem amigáveis. Só o fato de não permitir total = total + valor já tira muitos (a maioria?) dos programadores da zona de conforto. O que é bom.

Elm é incrível mesmo, a segurança que usar monadas e outras estruturas algebricas dá para sua aplicação junto aos princípios funcionais garante que se tudo compilar corretamente e obedecer as leis dessas estruturas a sua aplicação não vai dar erros de runtime que você já não espera ou tenha tratado no seu código.