Quais são as dores que a contextAPI resolve ?
No React quando temos vários níveis de propriedades sendo passadas de pai para filho, de filho para neto e assim sucessivamente, cometemos uma prática que chamamos de prop drilling ou na sua tradução perfuração de propriedades, que a depender da quantidade de componentes pode acabar complicando muito, deixando mais verboso o seu código, mais difícil a manutenção, e nós como bons programadores queremos poupar dor de cabeça, e pra isso o React tem um state management nativo que vem com intuito de solucionar essa dor, que é a contextAPI(como podemos ver na capa desse artigo).
Tá, mas como usar essa tal contextAPI ?
É indicado utilizar a context para compartilhar dados que podem ser considerados “globais” na sua aplicação. Usuário autenticado, idioma preferido, temas, são alguns casos comuns.
Mão no código!
- Vamos criar 3 components( App, ToggleTheme e Button). O componente App renderizará o componente ToggleTheme que renderizará o componente Button.
// Component App
function App() {
return (
<ToggleTheme />
);
};
// Component ToggleTheme
function ToggleTheme() {
return (
<Button />
);
};
// Component Button
function Button() {
return (
<button>Mudar tema</button>
);
};
- Agora importamos de dentro de React o createContext, com ele iremos criar o nosso contexto, e em seguida definimos o nosso ThemeContext que será o nosso contexto de "tema".
CreateContext recebe como parâmetro um valor padrão, como o nosso contexto é de tema o valor padrão será: "dark".
import { createContext } from 'react';
// Cada context nos permite passar um valor a fundo da árvore de componente
// sem explicitamente passa-la por cada componente.
const ThemeContext = createContext('dark');
Todos consumidores que são descendentes de um Provider serão renderizados novamente sempre que a prop value do Provider for alterada.
function App() {
const [theme, setTheme ] = useState('dark');
const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark')
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme}}>
<ToggleTheme />
</ThemeContext.Provider>
);
};
- Nosso componente ToggleTheme, não precisa mais passar o tema explicitamente. Não precisamos jogar nenhuma propriedade para dentro do componente Button.
function ToggleTheme() {
return (
<Button/>
);
};
- Por fim nosso componente Button que receberá os dados da nossa context. Pra isso vamos desestruturar de dentro de useContext o nosso state theme, e a nossa função toggleTheme.
useContext é uma função que recebe como parâmetro o nosso contexto
function Button() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
// Todas as vezes que o botão for clicado o valor de state será alterado
<button onClick={toggleTheme}>
// Valor do tema sendo mostrado em tela
{theme}
</button>
);
};
7.Ficando assim o nosso código final
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext('dark');
function App() {
const [theme, setTheme ] = useState('dark');
const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark')
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme}}>
<ToggleTheme />
</ThemeContext.Provider>
);
}
function ToggleTheme() {
return (
<Button/>
);
}
function Button() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button onClick={toggleTheme}>
{theme}
</button>
);
}
export default App;