É muito comum encontrarmos bastante conteúdo sobre utilização de props e states no React Native, mas em sua maioria, o material trás exemplos com situações bem mais avançadas.

Mas é bem escasso um material abordando situações mais básicas que ajudam a aplicar e relembrar o básico, só que nas versões mais recentes do React Native.

Então iremos vai falar um pouco aqui sobre:

  • Props.
  • States.
  • Hooks.
  • Hooks Personalizados.

Com exemplos bem básicos para você entender, fixar bem e ficar preparado para conteúdos mais avançados. Então acompanhe com agente nesta vídeo aula e no artigo:

Considerações Iniciais

No nosso exemplo iremos utilizar um contador básico que vai exibir um número e um botão para incrementar esse número.

React Native Props

As Props em React Native, são as propriedades que podemos passar de um componente para outro podendo ser utilizada internamente, seja para exibir ou aplicar alguma lógica própria do componente.

Por exemplo, imagine que temos um componente chamado Counter que simplesmente retorna uma <View> com um <Text> exibindo um número:

import React from "react";
import { View, Text } from "react-native";

const Counter = () => {
  return (
    <View>
      <Text>0</Text>
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

Agora se quisermos exibir um número diferente no componente Counter mas sem precisar alterar manualmente o número zero, temos que recorrer as Props:

import React from "react";
import { View, Text } from "react-native";

const Counter = ({ value }) => {
  return (
    <View>
      <Text>{value}</Text>
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter value={1} />
    </View>
  );
};

export default App;

Percebeu que as Props são recebidas no componente como se fossem propriedades de um método, seria mais ou menos como se estivéssemos fazendo isso:

function counter(value) {
  return "<h1>" + value + "</h1>";
}

//counter(1)
// -> <h1>1</h1>

E são passadas através da utilização do componente, como podemos ver:

<Counter value={1} />

podemos verificar que:

  • value = o nome da propriedade que poderemos acessar no componente Counter.
  • 1 = o valor da propriedade.

Então para resumir a utilização das Props, são basicamente variáveis que podemos passar para os nossos componentes, determinando um nome e um valor como vimos acima e que irão ser recebidas por eles como se fossem propriedades de função.

React Native States

Os States são valores que utilizamos em nossos componentes React que causam o efeito de renderização instantânea toda vez que o valor do State for alterado, isso da o efeito dinâmico e reativo para nossas aplicações.

Devemos ter em mente que os States são valores que não podemos trabalhar através de atribuições normais como, declarar uma variável e alterar o seu valor, por exemplo:

let value = 10;
value = 12;

Para fazermos algo semelhante com os States precisamos ter essa variável declarada no State do componente e ter uma função própria para alterar o valor.

Nas versões anteriores a 16.8 do React, para utilizar o State em um componente, precisávamos declarar os componentes em formato de classe, por exemplo:

import React, {Component} from 'react';
import {Text, View} from 'react-native';

export default class Counter extends Component {
  state = {
    counter: 0,
  };

  render() {
    return (
      <View>
        <Text> {this.state.counter} </Text>
      </View>
    );
  }
}

E se quisermos alterar o valor do State, precisamos utilizar o setState veja um exemplo:

import React, {Component} from 'react';
import {Text, View, Button} from 'react-native';

class Counter extends Component {
  state = {
    counter: 0,
  };

  render() {
    return (
      <View>
        <Text> {this.state.counter} </Text>
        <Button
          title="Clique Aqui"
          onPress={() => {
            this.setState({counter: this.state.counter + 1});
          }}
        />
      </View>
    );
  }
}

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

É por isso que nas versões mais recentes do React Native, introduziram o Hook useState, que facilita bastante nossa vida quando precisamos declarar uma variável no State do componente, podemos utilizar os componentes no formato de função e ainda assim ter um State, veja, vamos declarar a variável counter:

import React, { useState } from "react";
import { View, Text } from "react-native";

const Counter = () => {
  const [counter, setCounter] = useState(0);

  return (
    <View>
      <Text>{counter}</Text>
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

O useState é um hook que agente importa da biblioteca React e serve para podermos utilizar e manipular os States do componente.

Basicamente, para utilizá-lo, devemos declarar pensando nessa estrutura const [variavel, setVariavel] = useState(valorInicial), para nosso exemplo então:

const [counter, setCounter] = useState(0);

Onde:

  • counter = nome da variável.
  • setCounter = função para alterar o valor da variável.
  • 0 = valor inicial da variável.

E como utilizar o setCounter para alterarmos o valor da variável counter? Vejamos um exemplo de como utilizar nesse nosso caso:

import React, { useState } from "react";
import { View, Text, Button } from "react-native";

const Counter = () => {
  const [counter, setCounter] = useState(0);

  return (
    <View>
      <Text>{counter}</Text>
      <Button title="clique aqui" onPress={() => setCounter(1)} />
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

Explicando… Aqui, adicionamos um componente Button e colocamos no método onPress dele a chamada para o setCounter passando o valor 1.

Ao clicar nesse botão, nossa variável counter que foi iniciada com o valor 0 será modificada com o valor passado no setCounter(1) e irá renderizar novamente nosso componente Counter mostrando na tela o valor 1.

E se eu quiser agora realmente dar o efeito de um contador ao clicar no botão?

Basta alterar o valor de counter passado no método setCounter(1) para setCounter(counter + 1), ou seja, toda vez que eu clicar no botão o valor de counter vai ser atualizado para o valor de counter + 1.

Fica assim então:

import React, { useState } from "react";
import { View, Text, Button } from "react-native";

const Counter = () => {
  const [counter, setCounter] = useState(0);

  return (
    <View>
      <Text>{counter}</Text>
      <Button title="clique aqui" onPress={() => setCounter(counter + 1)} />
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

Viu como é bem fácil utilizar os state com o Hook useState ? 🙂

Hooks Personalizados

Como pudemos ver, os Hooks são forma mais recente de se trabalhar com os states (e támbem outros recursos do React).

No nosso exemplo até agora, trabalhamos apenas com um Hook fornecido pela api do React, o useState.

Mas será que é possível criar nossos próprios Hooks Personalizados? Sim! Vejamos como:

const useCounter = () => {
  const [value, setValue] = useState(0);

  return [value, setValue];
};

Por padrão, os Hooks devem utilizar sempre o prefixo use.

No nosso exemplo criamos um Hook chamado useCounter que abstraímos do nosso componente Counter.

Perceba que o retorno dele é [value, setValue], ou seja nosso Hook personalizado deve retornar um valor e uma função para alterar esse valor para que possamos utilizar nos nossos componentes.

Mas para que fazer essa abstração de criar um Hook personalizado se já estava tudo funcionando normalmente somente com o useState?

Bom, a vantagem é poder isolar a lógica do Hook em um lugar diferente e permitir sua reutilização em outros componentes.

Esta técnica é chamada de LogicHooks, que são Hooks que armazenam lógicas de uma aplicação tornando-as isoladas e também reutilizáveis.

Vamos incrementar o nosso Hook personalizado colocando nele a função setCounter abstraindo do nosso método onPress do Button.

const useCounter = () => {
  const [value, setValue] = useState(0);

  const setCounter = () => {
    setValue(value + 1);
  };

  return [value, setCounter];
};

Dessa forma podemos tirar a preocupação de criar uma função contadora nos nossos componentes e utilizar o nosso Hook useCounter para isso:

import React, { useState } from "react";
import { View, Text, Button } from "react-native";

const useCounter = () => {
  const [value, setValue] = useState(0);

  const setCounter = () => {
    setValue(value + 1);
  };

  return [value, setCounter];
};

const Counter = () => {
  const [counter, setCounter] = useCounter(0);

  return (
    <View>
      <Text>{counter}</Text>
      <Button title="clique aqui" onPress={() => setCounter()} />
    </View>
  );
};

const App = () => {
  return (
    <View>
      <Counter />
    </View>
  );
};

export default App;

Conclusão

Nesse artigo pudemos entender os conceitos básicos de Props, States e Hooks e também criamos nosso próprio Hook personalizado.

Esses conceitos são essenciais na vida do programador React e React Native, por isso, se você está pensando em entrar nesse mundo React, é bastante interessante e importante aprender bem a utilizá-los.

Por isso criamos esse conteúdo, para ajudar o pessoal a entender bem do básico, esses indispensáveis recursos do React.

E se você quer ver mais conteúdos como este não deixe de assistir o nosso JavaScript: Filter, Map, Reduce o Guia Supremo.

Neste guia, você vai aprender as 3 funções mais importantes do JavaScript que irão lhe ajudar demais no desenvolvimento de aplicativos.

Caso tenha alguma dúvida ou sugestão, coloca ai nos comentários. AH… Também conta ai pra gente oque achou desse conteúdo e se você deseja aprender mais sobre os Hooks com exemplos mais profissionais…