DEV Community

Altencir Junior
Altencir Junior

Posted on

Criando uma TodoList com React Native

Com o React Native, conseguimos criar diversas aplicações mobile para diferentes tipos de plataforma seja Android ou iOS. Uma das funcionalidades comuns em muitos aplicativos móveis é uma lista de tarefas, também chamada TodoList. Neste artigo, vamos aprender a criar uma TodoList em React Native.

Iniciando o projeto TodList-

Antes de tudo, é necessário criar um diretório para o nosso projeto, para isso usamos o seguinte comando, pois com ele iremos começar nossa aplicação:

npx create-expo-app -t expo-template-blank-typescript
Enter fullscreen mode Exit fullscreen mode

Após isso ele irá perguntar qual será o nome do projeto, o qual daremos o nome de: Desafio.

Feito isso temos nosso projeto e nele podemos separar nossos arquivos que iremos usar da seguinte maneira:

Image description

Seguindo o caminho Screens/Home/index.tsx podemos inserir nosso código para a TodoList.

Nosso código inicia fazendo as importações de useState para controlar o estado de mudança de nosso TodoList, também importamos ( View , Text, TextInput, TouchableOpacity, FlatList, Alert, Image) do react. Fazemos também uma importação de estilização da qual não iremos inserir neste código, mas será utilizada via StyleSheet. Também vamos importar um componente reservado para tarefas, chamado Tarefas. Ele ficará da seguinte maneira:

import React, {useState} from "react";

import { View , Text, TextInput, TouchableOpacity, FlatList, Alert, Image} from 'react-native';

import { styles } from "./style";

import { Tarefas} from "../../components/Tarefas"
Enter fullscreen mode Exit fullscreen mode

Com todas as importações feitas, começamos a criar nossa exportação da função Home(que iremos passar como componente, no App.tsx), que não apresenta parâmetros mas tem diversas consts de controle de estado:

 const [taskName , setTaskName] = useState('');
 const [tasks , setTask] = useState <String[]> ([]);
 const [isDarkMode, setIsDarkMode] = useState(false);
Enter fullscreen mode Exit fullscreen mode

A primera const, com useState taskName é onde será passado nossas tarefas. task servirá para listar nossas tarefas, e isDarkMode servirá para criar um "modo escuro" simples que irá trocar apenas o seu papel de parede.

Logo após, criamos a função handleTaskAdd para controlar resultados de envio da tarefa. Criamos uma const taskLowerCase que irá percorrer a listagem task por meio de .map convertendo qualquer informação escrita no campo de envio, para lowerCase(ou seja, converter todas as letras alfabéticas em strings minúsculas). Se ele perceber que a tarefa passada já está incluída, ou seja, já existe, retornaremos uma caixa de alerta com a mensagem: Tarefa existe, Essa tarefa já existe na lista.

E caso o taskName que é onde estamos escrevendo as tarefas, seja igual a 0, ou seja,não tenha nada escrito em seu TextInput(iremos falar mais a frente sobre o local que ficará armazenado o taskName), retornará uma mensagem de alerta revelando o espaço vazio. Finalizando, temos um setTask que serve para atualizar o estado da listagem de tarefas. Usamos o operador spread,que são os três pontos(...) criando um novo array onde inclui todos os valores anteriores e o novo valor adicionado, que é o taskName, e o setTaskName ('') ao final significa que é para limpar o valor do campo de entrada de texto ou outro elemento do formulário, para que o usuário possa inserir um novo valor.

function handleTaskAdd() {

      const taskLowerCase = tasks.map(task => task.toLowerCase())
      if (taskLowerCase.includes(taskName.toLowerCase())) {
        return Alert.alert("Tarefa existe", "Essa tarefa já existe na lista");
      }

      if (taskName.length === 0) {
        return Alert.alert("Espaço vazio", "Nenhuma tarefa foi digitada");

      }
      setTask( previewState => [...previewState ,taskName]);
      setTaskName ('');

    }
Enter fullscreen mode Exit fullscreen mode

Partimos para o handleTaskRemove que irá controlar a exclusão das tarefas, e caso clique no botão de excluir, ele irá apresentar um alerta de perguntando se desejo ou não remover a tarefa. O mesmo será para toggleDarkMode.

function handleTaskRemove(name: string) {
      Alert.alert("Remover",`Remover tarefa: ${name}?`,
      [
        {
          text: "SIM",
          onPress: () => setTask(previewState => previewState.filter(task => task !== name))
        },
        {
          text:"NÃO",
          style: "cancel"
        }
      ])
    }

    function toggleDarkMode() {
      setIsDarkMode(!isDarkMode);
    }
Enter fullscreen mode Exit fullscreen mode

Após isso, vamos para nosso return. Nele temos o View que irá receber a estilização padrão e isDarkMode, vamos adicionar uma imagem a tela, e também um botão TouchableOpacity qur irá controlar a mudança de estilos. Feito isso, criamos uma nova Vie, nela temos um TextInput com valor taskName e que muda com base no setTaskName. Teremos um botão que ao pressionar acionará ohandleTaskAdd` e nele, irá utilizar uma imagem que servirá como botão. Essa lógica fará com que o essa aplicação adicione novas tarefas dentro da FlatList:

`
return(

style={styles.logo}
source={require('../../components/icons/logo.png')}
/>

{isDarkMode ? "Modo Claro" : "Modo Escuro"}

    <View style={styles.form}>

      <TextInput 
        style={styles.input}
        placeholder = "Insira a tarefa aqui"
        placeholderTextColor= "#6B6B6B"
        onChangeText={setTaskName}
        value ={taskName}
      />

      <TouchableOpacity  
        onPress={handleTaskAdd}>
          <Image
            style={styles.buttonTask}
            source={require('../../components/icons/send.png')}
          />
      </TouchableOpacity>
Enter fullscreen mode Exit fullscreen mode

`

Juntando todo o nosso código, ele seria assim:

`
import React, {useState} from "react";

import { View , Text, TextInput, TouchableOpacity, FlatList, Alert, Image} from 'react-native';

import { styles } from "./style";

import { Tarefas} from "../../components/Tarefas"

export function Home() {
const [taskName , setTaskName] = useState('');
const [tasks , setTask] = useState ([]);
const [isDarkMode, setIsDarkMode] = useState(false);

function handleTaskAdd() {

  const taskLowerCase = tasks.map(task => task.toLowerCase())
  if (taskLowerCase.includes(taskName.toLowerCase())) {
    return Alert.alert("Tarefa existe", "Essa tarefa já existe na lista");
  }

  if (taskName.length === 0) {
    return Alert.alert("Espaço vazio", "Nenhuma tarefa foi digitada");

  }
  setTask( previewState => [...previewState ,taskName]);
  setTaskName ('');

}


function handleTaskRemove(name: string) {
  Alert.alert("Remover",`Remover tarefa: ${name}?`,
  [
    {
      text: "SIM",
      onPress: () => setTask(previewState => previewState.filter(task => task !== name))
    },
    {
      text:"NÃO",
      style: "cancel"
    }
  ])
}

function toggleDarkMode() {
  setIsDarkMode(!isDarkMode);
}
Enter fullscreen mode Exit fullscreen mode

return(

style={styles.logo}
source={require('../../components/icons/logo.png')}
/>

{isDarkMode ? "Modo Claro" : "Modo Escuro"}

    <View style={styles.form}>

      <TextInput 
        style={styles.input}
        placeholder = "Insira a tarefa aqui"
        placeholderTextColor= "#6B6B6B"
        onChangeText={setTaskName}
        value ={taskName}
      />

      <TouchableOpacity  
        onPress={handleTaskAdd}>
          <Image
            style={styles.buttonTask}
            source={require('../../components/icons/send.png')}
          />
      </TouchableOpacity>

    </View>

    <FlatList showsVerticalScrollIndicator ={false}

      data={tasks}
      keyExtractor={item => String(item)}
      renderItem={({ item }) => (
        <Tarefas
            key={String (item)}
            name = {String(item)} 
            onRemove ={()=> handleTaskRemove(`${item}`)}/>
      )}
    ListEmptyComponent={() => (
        <Image
          style={styles.noTasks}
          source={require('../../components/icons/list.png')}
        />
    )}  
    />
</View>
Enter fullscreen mode Exit fullscreen mode

);
}
`

Temos também, o componente Tarefas, que foi importado no Home. Ele tem como lógica configurar o que foi escrito nas tarefas, e inserir uma checkBox, para que possamos marcar como concluída a nossa tarefa:

`
import { Text,View, TouchableOpacity,Image} from "react-native";
import { styles } from "./style";
import React from 'react'
import BouncyCheckbox from "react-native-bouncy-checkbox";

type Props = {
name: string;
onRemove: () => void;
}

export function Tarefas({name, onRemove}: Props){
return(


size={25}
fillColor="green"
unfillColor="#FFFFFF"
onPress={(_isChecked: boolean) => {}}

/>
{name}

        <TouchableOpacity 
          onPress ={onRemove}>
          <Image
            style={styles.buttonTrash}
            source={require('../../components/icons/trash.png')}
          />
      </TouchableOpacity>
    </View>
)
Enter fullscreen mode Exit fullscreen mode

}
`

O resultado será a seguinte TodoList:

Image description

Espero que este artigo tenha ajudado você a criar uma TodoList e entender seu funcionamento. É possível ver esse projeto no meu gitHub pelo link a seguir: https://github.com/altencirsilvajr/Desafio

Top comments (0)