Em React Native/Expo, passar dados sem usar o getContext
(ou a API de Contexto) normalmente envolve prop drilling (passar dados através de propriedades) ou o uso de bibliotecas de gerenciamento de estado. Aqui está uma explicação detalhada de como passar dados entre componentes sem usar o Context API, junto com exemplos práticos:
1. Passagem de Dados por Propriedades (Prop Drilling)
A maneira mais direta de compartilhar dados entre componentes é passando-os diretamente de um componente pai para um componente filho através das props. Esse processo é conhecido como prop drilling.
No entanto, o prop drilling pode se tornar complicado quando você precisa passar dados por muitos componentes aninhados.
Exemplo: Prop Drilling
Neste exemplo, passamos dados do componente raiz App
para um componente UserDisplay
.
import React, { useState } from 'react';
import { Text, Button, View } from 'react-native';
// Componente Filho
const UserDisplay = ({ user, setUser }) => {
return (
<View>
<Text>Usuário Atual: {user}</Text>
<Button title="Trocar Usuário" onPress={() => setUser("Jane Doe")} />
</View>
);
};
// Componente Intermediário
const IntermediateComponent = ({ user, setUser }) => {
return (
<View>
<Text>Componente Intermediário</Text>
<UserDisplay user={user} setUser={setUser} />
</View>
);
};
// Componente Raiz
export default function App() {
const [user, setUser] = useState("John Doe");
return (
<View>
<Text>Componente App</Text>
<IntermediateComponent user={user} setUser={setUser} />
</View>
);
}

Explicação:
- O estado
user
é mantido no componenteApp
. - O
user
e a funçãosetUser
são passados para oIntermediateComponent
, que por sua vez os passa para o componenteUserDisplay
. - Embora seja simples para árvores de componentes pequenas, esse método pode ser complexo quando muitos componentes precisam de dados.
2. “Lifting State Up” (Elevar o Estado)
Elevar o estado é um padrão onde você move o estado para o ancestral comum mais próximo dos componentes que precisam dele.
Exemplo: Lifting State Up
Aqui, dois componentes irmãos compartilham o mesmo estado por meio de um componente pai.
import React, { useState } from 'react';
import { Text, Button, View } from 'react-native';
// Componente Filho 1
const UserDisplay = ({ user }) => {
return (
<View>
<Text>Usuário Atual: {user}</Text>
</View>
);
};
// Componente Filho 2
const UserChange = ({ setUser }) => {
return (
<View>
<Button title="Trocar Usuário" onPress={() => setUser("Jane Doe")} />
</View>
);
};
// Componente Pai
export default function App() {
const [user, setUser] = useState("John Doe");
return (
<View>
<UserDisplay user={user} />
<UserChange setUser={setUser} />
</View>
);
}
Explicação:
- O estado
user
e a funçãosetUser
são mantidos no componenteApp
e passados para os dois componentes filhos. - Um componente exibe o nome do usuário, enquanto o outro altera o nome do usuário.
- Esse padrão evita a repetição de estados e permite que múltiplos componentes compartilhem o mesmo estado.
3. Uso de Bibliotecas de Gerenciamento de Estado (Redux, Zustand, etc.)
Em aplicações maiores, o prop drilling ou o “lifting state up” podem se tornar difíceis de gerenciar. Nesse caso, usar bibliotecas como Redux ou Zustand ajuda a organizar o estado da aplicação.
Exemplo: Passando Dados com Redux
Com o Redux, o estado é mantido em um estado global acessível a qualquer componente, sem a necessidade de passar props manualmente.
Exemplo Simplificado com Redux:
import React from 'react';
import { Text, Button, View } from 'react-native';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { createStore } from 'redux';
// Estado inicial
const initialState = {
user: "John Doe"
};
// Função reducer
const reducer = (state = initialState, action) => {
switch (action.type) {
case "SET_USER":
return { ...state, user: action.payload };
default:
return state;
}
};
// Criação da store
const store = createStore(reducer);
// Componente para exibir o usuário
const UserDisplay = () => {
const user = useSelector((state) => state.user);
return (
<View>
<Text>Usuário Atual: {user}</Text>
</View>
);
};
// Componente para alterar o usuário
const UserChange = () => {
const dispatch = useDispatch();
return (
<View>
<Button title="Trocar Usuário" onPress={() => dispatch({ type: "SET_USER", payload: "Jane Doe" })} />
</View>
);
};
// Componente raiz com o Redux Provider
export default function App() {
return (
<Provider store={store}>
<View>
<UserDisplay />
<UserChange />
</View>
</Provider>
);
}

Explicação:
- O Redux armazena o estado global da aplicação.
- O
useSelector
permite que componentes leiam o estado da store global. - O
useDispatch
permite que componentes enviem ações para atualizar o estado.
Comparação de Métodos
Método | Descrição | Quando Usar |
---|---|---|
Prop Drilling | Dados são passados de um componente pai para os filhos via props. | Ideal para hierarquias simples ou quando poucos componentes precisam dos dados. |
Lifting State Up | O estado é movido para o ancestral comum mais próximo dos componentes que precisam compartilhá-lo. | Útil quando componentes no mesmo nível hierárquico precisam de acesso ao mesmo estado. |
Redux/Zustand | Cria um estado global acessível por qualquer componente sem a necessidade de passar props manualmente. | Melhor para grandes aplicações com muitos componentes compartilhando o mesmo estado. |
Deixe um comentário