Tutorial

Como usar o roteamento com React Navigation no React Native

React

Introdução

React Navigation é uma biblioteca popular para roteamento e navegação em uma aplicação React Native.

Essa biblioteca ajuda a resolver o problema de navegar entre várias telas e compartilhar dados entre elas.

Ao final deste tutorial, teremos uma rede social rudimentar. Ela irá exibir o número de conexões que um usuário possui e fornecer uma maneira de se conectar com amigos adicionais. Usaremos este aplicativo de exemplo para explorar como navegar por telas de aplicativos móveis usando react-navigation.

Pré-requisitos

Para completar este tutorial, será necessário:

Nota: se você trabalhou com react-navigation no passado, poderá encontrar algumas diferenças. Consulte a documentação para guias sobre como migrar a partir do 3.x e como migrar a partir do 4.x.

Este tutorial foi testado com o Node v14.7.0, npm v6.14.7, react v16.13.1, react-native v0.63.2, @react-navigation/native v5.7.3 e @react-navigation/stack v5.9.0.

Passo 1 — Criando um novo aplicativo React Native

Primeiro, crie um novo aplicativo React Native executando o seguinte comando em seu terminal:

  • npx react-native init MySocialNetwork --version 0.63.2

Em seguida, navegue até o novo diretório:

  • cd MySocialNetwork

E inicie o aplicativo para o iOS:

  • npm run ios

Alternativamente, para o Android:

  • npm run android

Nota: se tiver quaisquer problemas, consulte troubleshooting issues for React Native CLI.

Isso irá criar um esqueleto de projeto.para você. Isso não se parece com uma rede social neste momento. Vamos corrigir isso.

Abra o App.js:

  • nano App.js

Substitua o conteúdo de App.js pelo código a seguir para exibir uma mensagem de boas-vindas:

App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Welcome to MySocialNetwork!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

Salve o arquivo. Agora, ao executar o aplicativo, uma mensagem Welcome to MySocialNetwork! aparecerá em seu simulador.

No próximo passo, você irá adicionar mais telas ao seu aplicativo.

Passo 2 — Criando as telas HomeScreen e FriendsScreen

Atualmente, você possui uma única tela exibindo uma mensagem de boas-vindas. Neste passo, você irá criar as duas telas para o seu aplicativo: HomeScreen e FriendsScreen.

HomeScreen

Seu aplicativo precisará de uma tela HomeScreen. HomeScreen irá exibir o número de amigos que já estão em sua rede.

Pegue o código de App.js e adicione-o a um novo arquivo chamado HomeScreen.js:

  • cp App.js HomeScreen.js

Abra o HomeScreen.js:

  • nano HomeScreen.js

Modifique HomeScreen.js para usar HomeScreen em vez de App:

HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>You have (undefined) friends.</Text>
      </View>
    );
  }
}

// ...

export default HomeScreen;

Esse código irá produzir um placeholder de mensagem You have (undefined) friends. Você fornecerá um valor mais tarde.

FriendsScreen

Seu aplicativo também precisará de uma tela FriendsScreen. Em FriendsScreen você será capaz de adicionar novos amigos.

Pegue o código de App.js e adicione-o a um novo arquivo chamado FriendScreen.js:

  • cp App.js FriendsScreen.js

Abra o FriendsScreen.js:

  • nano FriendsScreen.js

Modifique FriendScreen.js para usar FriendScreen em vez de App:

FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

class FriendsScreen extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Add friends here!</Text>
      </View>
    );
  }
}

// ...

export default FriendsScreen;

Esse código irá produzir um Add friends here! como mensagem.

Neste ponto, você tem as telas HomeScreen e FriendsScreen. No entanto, não há nenhuma maneira de navegar entre elas. Você criará essa funcionalidade no próximo passo.

Passo 3 — Usando StackNavigator com React Navigation

Para navegar entre telas, você usará um StackNavigator. Um StackNavigator funciona exatamente como uma pilha de chamada. Cada tela que você navegar é enviada para o topo da pilha. Cada vez que você pressiona o botão voltar, as telas saem do topo da pilha.

Primeiro, instale @react-navigation/native:

  • npm install @react-navigation/native@5.7.3

Em seguida, instale o @react-navigation/stack e suas respectivas dependências:

  • npm install @react-navigation/stack@5.9.0 @react-native-community/masked-view@0.1.10 react-native-screens@2.10.1 react-native-safe-area-context@3.1.4 react-native-gesture-handler@1.7.0

Nota: se você estiver desenvolvendo para iOS, é necessário navegar até o diretório ios e executar pod install.

Em seguida, revisite o App.js:

  • nano App.js

Adicione NavigationContainer e createStackNavigator ao App.js:

App.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

Em seguida, substitua o conteúdo de render:

App.js
// ...

class App extends React.Component {
  render() {
    return (
      <NavigationContainer>
        <Stack.Navigator>
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

// ...

Aninhado dentro de <Stack.Navigator>, adicione HomeScreen:

App.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';

const Stack = createStackNavigator();

class App extends React.Component {
  render() {
    return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen
            name="Home"
            component={HomeScreen}
          />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

// ...

Esse código cria uma pilha muito pequena para o seu navigator com apenas uma tela: HomeScreen.

Aninhado dentro de <Stack.Navigator>, adicione FriendsScreen:

App.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
import FriendsScreen from './FriendsScreen';

const Stack = createStackNavigator();

class App extends React.Component {
  render() {
    return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen
            name="Home"
            component={HomeScreen}
          />
          <Stack.Screen
            name="Friends"
            component={FriendsScreen}
          />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

// ...

Esse código adiciona a FriendsScreen ao navigator.

Nota: isso difere de como createStackNavigator foi usado em versões anteriores do React Navigation.

Agora, o navigator está ciente de suas duas telas.

Adicionando botões à HomeScreen e FriendsScreen

Finalmente, adicione botões para alternar entre as duas telas.

Em HomeScreen.js, adicione o seguinte código:

HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>You have (undefined) friends.</Text>

        <Button
          title="Add some friends"
          onPress={() =>
            this.props.navigation.navigate('Friends')
          }
        />
      </View>
    );
  }
}

// ...

Em FriendsScreen.js, adicione o seguinte código:

FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

class FriendsScreen extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Add friends here!</Text>

        <Button
          title="Back to home"
          onPress={() =>
            this.props.navigation.navigate('Home')
          }
        />
      </View>
    );
  }
}

// ...

Vamos falar sobre this.props.navigation. Uma vez que sua tela esteja incluída no StackNavigator, ela herda automaticamente muitas propriedades úteis do objeto navigation. Neste caso, você usou navigate para mover-se para uma página diferente.

HomeScreen e FriendsScreen

Se você abrir seu simulador agora, poderá navegar entre HomeScreen e FriendsScreen.

Passo 4 — Usando Context para passar dados para outras telas

Neste passo, você criará um array de possíveis amigos — Alice, Bob e Sammy — e um array vazio de amigos atuais. Você também criará funcionalidade para que o usuário adicione possíveis amigos aos seus amigos atuais.

Abra App.js:

  • nano App.js

Adicione possibleFriends e currentFriends ao estado do componente:

App.js
// ...

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      possibleFriends: [
        'Alice',
        'Bob',
        'Sammy',
      ],
      currentFriends: [],
    }
  }

  // ...
}

// ...

Em seguida, adicione uma função para mover um possível amigo para a lista de amigos atuais:

App.js
// ...

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      possibleFriends: [
        'Alice',
        'Bob',
        'Sammy',
      ],
      currentFriends: [],
    }
  }

  addFriend = (index) => {
    const {
      currentFriends,
      possibleFriends,
    } = this.state

    // Pull friend out of possibleFriends
    const addedFriend = possibleFriends.splice(index, 1)

    // And put friend in currentFriends
    currentFriends.push(addedFriend)

    // Finally, update the app state
    this.setState({
      currentFriends,
      possibleFriends,
    })
  }

  // ...
}

// ...

Neste ponto, terminamos de criar a funcionalidade para adicionar amigos.

Adicionando FriendsContext ao App

Agora, você pode adicionar amigos em App.js, mas você desejará adicioná-los ao FriendsScreen.js e exibí-los em HomeScreen.js. Como este projeto é construído com React, é possível injetar essa funcionalidade em suas telas com contexto.

Nota: em versões anteriores do React Navigation, era possível usar screenProps para compartilhar dados entre telas. Na versão atual do React Navigation, recomenda-se usar React Context para compartilhar dados entre telas.

Para evitar uma referência circular, você desejará um novo arquivo FriendsContext:

  • nano FriendsContext.js

Exporte FriendsContext:

FriendsContext
import React from 'react';

export const FriendsContext = React.createContext();

Abra App.js:

  • nano App.js

Adicione o FriendsContext:

App.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { FriendsContext } from './FriendsContext';
import Home from './Home';
import Friends from './Friends';

const Stack = createStackNavigator();

class App extends React.Component {
  // ...

  render() {
    return (
      <FriendsContext.Provider>
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={Home}
            />
            <Stack.Screen
              name="Friends"
              component={Friends}
            />
          </Stack.Navigator>
        </NavigationContainer>
      </FriendsContext.Provider>
    );
  }
}

// ...

Esse código estabelece FriendsContext como um novo objeto Context e encapsula o NavigationContainer em um componente Context.Provider para que qualquer filho na árvore de componentes possa se inscrever para mudanças de contexto.

Como você não está usando View ou Text, é possível remover essas importações do react-native.

Você precisará fornecer um value para tornar os dados acessíveis pelos consumidores:

App.js
// ...

class App extends React.Component {
  // ...

  render() {
    return (
      <FriendsContext.Provider
        value={
          {
            currentFriends: this.state.currentFriends,
            possibleFriends: this.state.possibleFriends,
            addFriend: this.addFriend
          }
        }
      >
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={Home}
            />
            <Stack.Screen
              name="Friends"
              component={Friends}
            />
          </Stack.Navigator>
        </NavigationContainer>
      </FriendsContext.Provider>
    );
  }
}

// ...

Isso permitirá que HomeScreen e FriendsScreen façam referência a qualquer alteração de contexto para currentFriends e possibleFriends.

Agora, você pode trabalhar fazendo referência ao contexto em suas telas.

Adicionando FriendsContext à HomeScreen

Neste passo, você irá configurar o aplicativo para exibir a contagem atual de amigos.

Abra o HomeScreen.js:

  • nano HomeScreen.js

E adicione o FriendsContext:

HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';

class HomeScreen extends React.Component {
  // ...
}
HomeScreen.contextType = FriendsContext;

// ...

Esse código estabelece um Class.contextType. Agora, você pode acessar contexto em suas telas.

Por exemplo, vamos fazer com que sua HomeScreen exiba quantos currentFriends você tem:

HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';

class Home extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>You have { this.context.currentFriends.length } friends!</Text>

        <Button
          title="Add some friends"
          onPress={() =>
            this.props.navigation.navigate('Friends')
          }
        />
      </View>
    );
  }
}
HomeScreen.contextType = FriendsContext;

// ...

Se você abrir seu aplicativo novamente no simulador e visualizar a HomeScreen, você verá a mensagem: You have 0 friends!.

Adicionando FriendsContext à FriendsScreen

Neste passo, você irá configurar o aplicativo para exibir os possíveis amigos e fornecer botões para adicioná-los aos amigos atuais.

Em seguida, abra o FriendsScreen.js:

  • nano FriendsScreen.js

E adicione o FriendsContext:

FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';

class FriendsScreen extends React.Component {
  // ...
}
FriendsScreen.contextType = FriendsContext;

// ...

Esse código estabelece um Class.contextType.

Agora, crie um botão para adicionar amigos em FriendsScreen.js:

FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';

class Friends extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Add friends here!</Text>

        {
          this.context.possibleFriends.map((friend, index) => (
            <Button
              key={ friend }
              title={ `Add ${ friend }` }
              onPress={() =>
                this.context.addFriend(index)
              }
            />
          ))
        }

        <Button
          title="Back to home"
          onPress={() =>
            this.props.navigation.navigate('Home')
          }
        />
      </View>
    );
  }
}
FriendsScreen.contextType = FriendsContext;

// ...

Se você abrir seu aplicativo novamente no simulador e visualizar a FriendsScreen, você verá uma lista de amigos a adicionar.

HomeScreen com 0 currentFriends e FriendScreen com 3 possibleFriends

Se você visitar a FriendsScreen e clicar no botão para adicionar amigos, verá a lista de possibleFriends diminuir. Se você visitar HomeScreen, você verá o número de amigos crescer.

Agora, você pode navegar entre telas e compartilhar dados entre elas.

Conclusão

Neste tutorial, criamos um exemplo de aplicativo React Native com várias telas. Usando React Navigation, criamos uma maneira de navegar entre telas. Usando React Context, desenvolvemos uma maneira de compartilhar dados entre telas.

O código fonte completo para este projeto está disponível no GitHub.

Se você quiser mergulhar mais profundamente no React Navigation, confira sua documentação.

React Navigation não é a única solução de roteamento e navegação. Há também React Native Navigation, React Native Router Flux, e React Router Native.

Se quiser aprender mais sobre o React, dê uma olhada em nossa série Como programar no React.js, ou confira nossa página do tópico React para exercícios e projetos de programação.

Creative Commons License