De fato, injeção de dependências surge, "originalmente" num contexto de orientação a objetos, inclusive uma das ideias desse post era mostrar que também é plenamente possível, e até menos burocrático, de aplicar essa técnica num contexto mais """funcional""".
Respondendo a sua pergunta sobre o React: Sim, é possível usar injeção de dependências com qualquer coisa, inclusive com o React e seus componentes, segue um exemplo abaixo:
Imagine que você tem um componente <Hero />
que representa a seção "Hero" da homepage da sua aplicação e, dentro dessa <Hero />
, você tem um subcomponente <HeroImage />
.
export const Hero = () => {
// Esse componente pode fazer várias coisas
// na sua implementação e retornar vários outros
// componentes, mas por simplicidade,
// vamos fingir que ele retorna somente o <HeroImage />
return (
<HeroImage />
);
}
Vamos considerar que esse <HeroImage />
possui duas implementações diferentes porque estamos fazendo um teste A/B, de forma que metade dos nossos usuários vai receber uma implementação e a outra metade, a outra.
Podemos adaptar o <Hero />
(que afinal é uma função), da seguinte maneira:
export const makeHero = ({ HeroImage }) => () => {
return (
<HeroImage />
);
}
// Aqui estou assumindo que a variante está vindo de uma
// variável de ambiente, mas ela poderia vir de qualquer outro
// lugar
export const Hero = makeHero({
HeroImage: process.env.HERO_IMAGE_VARIANT === "A" ? HeroImageA : HeroImageB
})
Perceba que continuamos exportando o componente <Hero />
e a assinatura dele continua exatamente igual, de forma que quem consome esse componente não precisa fazer nenhuma mudança.
Obs: Aqui a gente está escolhendo a implementação do <HeroImage />
em "boot time", ou seja, logo que a aplicação é "inicializada", porém é possível fazer isso mais "adiante" na aplicação, por exemplo, puxando a variante que vamos utilizar de uma API, porém para isto precisaríamos de uma maneira um pouco mais sofisticada de utilizar injeção de dependência, como por exemplo usando um container.