A Context é uma excelente forma de gerenciar estados em aplicações React e hoje em dia em muitos cenários dispensam o uso de bibliotecas adicionais para tal fim.
Uma das vantagens é a facilidade e simplicidade de testar os componentes que fazem uso de contextos com react-testing-library
.
Veja como costumo fazer nos meus projetos:
export type User = {
name: string;
};
import { createContext } from 'react';
import { User } from './user';
export const UserContext = createContext<User>({} as User);
import useSWR from 'swr';
import { User } from './user';
import { UserContext } from './user-context';
type Props = {
children: React.ReactNode;
};
export function UserProvider({ children }: Props) {
const { data, isLoading, error } = useSWR<User>('/api/user');
if (error) {
return <div>Erro ao carregar usuário</div>;
}
if (isLoading) {
return <div>Carregando...</div>;
}
return (
<UserContext.Provider value={data || ({} as User)}>
{children}
</UserContext.Provider>
);
}
import { useUser } from './useUser';
export function UserGreeter() {
const user = useUser();
if (user.name) {
return <div>Olá, {user.name}!</div>;
}
return <div>Olá, visitante!</div>;
}
Vamos garantir no teste que a regra de saudação seja respeitada corretamente:
import { render, screen } from '@testing-library/react';
import { UserGreeter } from './user-greeter';
import { UserProviderMock } from './user-provider-mock';
describe('UserGreeter', () => {
it('should greet the user', () => {
render(
<UserProviderMock>
<UserGreeter />
</UserProviderMock>,
);
expect(screen.getByText('Olá, John Doe!')).toBeInTheDocument();
});
it('should greet the anonymous user', () => {
render(
<UserProviderMock value={{}}>
<UserGreeter />
</UserProviderMock>,
);
expect(screen.getByText('Olá, visitante!')).toBeInTheDocument();
});
});
Observe que criei o UserProviderMock
com valores padrão, para evitar repetições em todos os testes dos componentes que dependem do User
:
import { User } from './user';
import { UserContext } from './user-context';
type Props = {
children: React.ReactNode;
value?: Partial<User>;
};
export function UserProviderMock({ children, value }: Props) {
return (
<UserContext.Provider value={{ name: 'John Doe', ...value }}>
{children}
</UserContext.Provider>
);
}
Você ainda acha necessário o uso de bibliotecas de gerenciamento de estado? Por favor, deixe sua opinião nos comentários.
Top comments (0)