É muito comum para desenvolvedores usarem SQLite , um Biblioteca em linguagem C, como armazenamento de dados em aplicativos móveis. O SQLite é especialmente útil para aplicativos off-line e muitas plataformas incluem suporte para SQLite pronto para uso, tornando-o fácil de instalar.

Neste artigo, usaremos o SQLite em um aplicativo React Native para configurar um aplicativo simples de lista de tarefas que nos mostrará como todas as operações CRUD estão funcionando. Também usaremos o TypeScript por causa de suas vantagens, como qualidade de código e facilidade de manutenção.

Pré-requisitos:

  • Noções básicas de React e React Native
  • Familiaridade com TypeScript

Primeiros passos

Criaremos um aplicativo de lista de tarefas que inclui o seguinte:

  • Botão Concluído : limpar os itens concluídos
  • Botão Adicionar tarefas : adicione novos itens
  • Duas chamadas useState : uma para manter uma lista de tarefas e uma para rastrear novos itens de tarefas
  • Componente do aplicativo: lida com eventos do usuário, como adição e exclusão de itens da lista de tarefas
  • Componente mudo: mostra um item da lista de tarefas

Observe que usaremos um conjunto de componentes funcionais e várias novas APIs de gancho para obter o gerenciamento de estado.

Configurando React Native e TypeScript

Começaremos criando um aplicativo React Native usando TypeScript:

 npx react-native init MyApp--template react-native-template-typescript 

Você pode clonar o aplicativo React e trabalhar enquanto lê o artigo.

Você verá que há dois branches no repositório, start e main . Começaremos com o branch start .

Apresentando SQLite

Vamos apresentar o SQLite ao nosso aplicativo. Para se conectar ao SQLite, vamos usar o react-native-sqlite-storage biblioteca .

Para instalar o SQLite, execute o seguinte código em seu terminal:

 npm install--save react-native-sqlite-storage 

Instalar pacotes React Native

iOS

Se você estiver usando iOS, execute o comando abaixo para instalar os pacotes React Native necessários:

 cd ios && pod install && cd.. 

Se você estiver executando o React Native versão 0.59 ou inferior, terá duas opções para instalar os pacotes do React Native, dependendo se estiver usando CocoaPods.

Com CocoaPods:

Se você estiver executando o CocoaPods, adicione o código abaixo ao seu podfile:

 pod'React',: path=>'../node_modules/react-native'
pod'react-native-sqlite-storage',: path=>'../node_modules/react-native-sqlite-storage'

Execute pod install ou pod update .

Sem CocoaPods

Se você não estiver executando o CocoaPods, deverá usar o link react-native . Se você encontrar algum erro, terá que abrir o projeto do Xcode e adicionar dependências manualmente. Para obter mais detalhes, consulte a documentação da biblioteca .

Android

Se estiver usando o SQLite do seu dispositivo em React Native.60 ou superior, não será necessário realizar nenhuma etapa extra.

No entanto, se estiver usando SQLite empacotado com a biblioteca react-native-sqlite-storage , você pode adicionar o código abaixo ao seu react-native.config.js arquivo:

 module.exports={ ..., dependências: { ..., "react-native-sqlite-storage": { plataformas: { android: { sourceDir: "../node_modules/react-native-sqlite-storage/platforms/android-native", packageImportPath:"import io.liteglue.SQLitePluginPackage;", packageInstance:"new SQLitePluginPackage ()" } } } ... } ...
};

Se você estiver executando uma versão mais antiga do React Native, deverá atualizar manualmente os arquivos Gradle . Para obter a configuração completa, consulte a documentação da biblioteca .

Implementar um serviço de armazenamento de dados

Agora, estamos prontos para implementar um serviço de armazenamento de dados. Apresentaremos um novo arquivo .ts chamado db-service.ts , onde podemos adicionar todas as nossas operações db . Primeiro, vamos criar um método para obter uma conexão db .

Como estamos usando o TypeScript, podemos instalar @ types/react-native-sqlite-storage para usar os tipos incluídos. Se você se limitar ao JavaScript, não precisará instalar esta biblioteca.

Adicione o método de conexão db usando o código abaixo:

 import {openDatabase} de'react-native-sqlite-storage'; export const getDBConnection=async ()=> { retornar openDatabase ({nome:'todo-data.db', localização:'padrão'});
};

Se uma tabela ainda não existe quando iniciamos o aplicativo, precisamos criar uma. Execute o seguinte código para adicionar outro método:

 export const createTable=async (db: SQLiteDatabase)=> { //cria a tabela se não existir const query=`CREATE TABLE IF NOT EXISTS $ {tableName} ( valor TEXTO NÃO NULO ); `; aguardar db.executeSql (consulta);
};

Como estamos usando APIs baseadas em promessa na biblioteca, é importante adicionar o código abaixo ao nosso arquivo db-service.ts :

 enablePromise (true);

A seguir, adicionaremos métodos para salvar, excluir e obter nossos itens de tarefas pendentes. Depois de adicionar esses métodos, nosso arquivo de serviço db se parecerá com o bloco de código abaixo:

 import {enablePromise, openDatabase, SQLiteDatabase} de'react-native-sqlite-storage';
importar {ToDoItem} de'../models'; const tableName='todoData'; enablePromise (true); export const getDBConnection=async ()=> { retornar openDatabase ({nome:'todo-data.db', localização:'padrão'});
}; export const createTable=async (db: SQLiteDatabase)=> { //cria a tabela se não existir const query=`CREATE TABLE IF NOT EXISTS $ {tableName} ( valor TEXTO NÃO NULO ); `; aguardar db.executeSql (consulta);
}; export const getTodoItems=async (db: SQLiteDatabase): Promise => { tentar { const todoItems: ToDoItem []=[]; resultados const=await db.executeSql (`SELECT rowid as id, value FROM $ {tableName}`); results.forEach (result=> { for (let index=0; index  { const insertQuery= `INSERT OR REPLACE INTO $ {tableName} (rowid, value) values` + todoItems.map (i=> `($ {i.id},'$ {i.value}')`).join (','); return db.executeSql (insertQuery);
}; export const deleteTodoItem=async (db: SQLiteDatabase, id: number)=> { const deleteQuery=`DELETE from $ {tableName} onde rowid=$ {id}`; esperar db.executeSql (deleteQuery);
}; export const deleteTable=async (db: SQLiteDatabase)=> { const query=`drop table $ {tableName}`; aguardar db.executeSql (consulta);
};

Adicionamos um método deleteTable , que será útil quando estivermos desenvolvendo nosso aplicativo. Posteriormente, adicionaremos um recurso para usuários que limpa todos os dados usando o método deleteTable .

Podemos usar rowid , que vem com o SQLite, como chave primária. Atualizamos nossos itens de tarefas para ter um ID e um valor em vez de uma string simples para que possamos excluir itens facilmente.

A seguir, adicionaremos um modelo para nosso tipo ToDoItem . Adicione o seguinte código em um arquivo chamado index.ts em outra pasta chamada modelos em:

 exportar tipo ToDoItem={ número de identidade; valor: string;
};

Usando o serviço db

Temos que usar nosso serviço db em App.tsx . Siga estas quatro etapas:

1.) Atualize o componente ToDoItem e o componente App para usar o novo tipo ToDoItem
2.) Carregar dados do SQLite
3.) Salve os dados no db
4.) Atualize os itens excluídos no db

Primeiro, vamos terminar de configurar nosso db , então daremos uma olhada no resultado final de App.tsx e ToDoItem.tsx arquivos.

Carregando dados

Para carregar os dados em nosso aplicativo, usaremos os ganchos useEffect e useCallback :

 const loadDataCallback=useCallback (async ()=> { tentar { const initTodos=[{id: 0, value:'go to shop'}, {id: 1, value:'coma pelo menos um alimentos saudáveis'}, {id: 2, value:'Faça alguns exercícios'}] ; const db=espera getDBConnection (); aguarde a tabela de criação (db); const storedTodoItems=await getTodoItems (db); if (storedTodoItems.length) { setTodos (storedTodoItems); } senão { aguarde saveTodoItems (db, initTodos); setTodos (initTodos); } } catch (erro) { console.error (erro); } }, []); useEffect (()=> { loadDataCallback (); }, [loadDataCallback]);

No snippet de código acima, estamos lendo dados do db . Se tivermos itens de tarefas pendentes armazenados, inicializamos o aplicativo com eles. Do contrário, manteremos os valores iniciais no db e inicializaremos o aplicativo usando esses dados.

Adicionando um item

Para adicionar um item de tarefa, execute o seguinte código:

 const addTodo=async ()=> { if (! newTodo.trim ()) return; tentar { const newTodos=[... todos, { id: todos.reduce ((acc, cur)=> { if (cur.id> acc.id) return cur; return acc; }). id + 1, valor: newTodo }]; setTodos (newTodos); const db=espera getDBConnection (); aguarde saveTodoItems (db, newTodos); setNewTodo (''); } catch (erro) { console.error (erro); } };

Excluindo um item

Por último, execute o código abaixo para excluir um item de tarefa:

 const deleteItem=async (id: número)=> { tentar { const db=espera getDBConnection (); aguarde deleteTodoItem (db, id); todos.splice (id, 1); setTodos (todos.slice (0)); } catch (erro) { console.error (erro); } };

Nosso arquivo final App.tsx deve ser semelhante ao código abaixo:

/** * Amostra de aplicativo nativo React * https://github.com/facebook/react-native * * Gerado com o modelo TypeScript * https://github.com/react-native-community/react-native-template-typescript * * @format */
import React, {useCallback, useEffect, useState} de'react';
import { Botão, SafeAreaView, ScrollView, Barra de status, StyleSheet, Texto, TextInput, useColorScheme, Visualizar,
} de'react-native';
import {ToDoItemComponent} de'./components/ToDoItem';
importar {ToDoItem} de'./models';
import {getDBConnection, getTodoItems, saveTodoItems, createTable, clearTable, deleteTodoItem} de'./services/db-service';
const App=()=> { const isDarkMode=useColorScheme ()==='escuro'; const [todos, setTodos]=useState  ([]); const [newTodo, setNewTodo]=useState (''); const loadDataCallback=useCallback (async ()=> { tentar { const initTodos=[{id: 0, value:'go to shop'}, {id: 1, value:'coma pelo menos um alimentos saudáveis'}, {id: 2, value:'Faça alguns exercícios'}] ; const db=espera getDBConnection (); aguarde a tabela de criação (db); const storedTodoItems=await getTodoItems (db); if (storedTodoItems.length) { setTodos (storedTodoItems); } senão { aguarde saveTodoItems (db, initTodos); setTodos (initTodos); } } catch (erro) { console.error (erro); } }, []); useEffect (()=> { loadDataCallback (); }, [loadDataCallback]); const addTodo=async ()=> { if (! newTodo.trim ()) return; tentar { const newTodos=[... todos, { id: todos.length? todos.reduce ((acc, cur)=> { if (cur.id> acc.id) return cur; return acc; }). id + 1: 0, valor: newTodo }]; setTodos (newTodos); const db=espera getDBConnection (); aguarde saveTodoItems (db, newTodos); setNewTodo (''); } catch (erro) { console.error (erro); } }; const deleteItem=async (id: número)=> { tentar { const db=espera getDBConnection (); aguarde deleteTodoItem (db, id); todos.splice (id, 1); setTodos (todos.slice (0)); } catch (erro) { console.error (erro); } }; Retorna (      Aplicativo ToDo    {todos.map ((todo)=> (  ))}    setNewTodo (text)}/>     );
};
estilos const=StyleSheet.create ({ appTitleView: { marginTop: 20, justifyContent:'center', flexDirection:'row', }, appTitleText: { fontSize: 24, fontWeight:'800' }, textInputContainer: { marginTop: 30, marginLeft: 20, marginRight: 20, borderRadius: 10, borderColor:'preto', borderWidth: 1, justifyContent:'flex-end' }, textInput: { borderWidth: 1, borderRadius: 5, altura: 30, margem: 10, backgroundColor:'rosa' },
});
exportar aplicativo padrão;

Por último, nosso arquivo final ToDoItem.tsx deve ter o seguinte bloco de código:

 import React from'react';
import { Botão, StyleSheet, Texto, Visualizar,
} de'react-native';
importar {ToDoItem} de'../models';
export const ToDoItemComponent: React.FC <{ todo: ToDoItem; deleteItem: Function;
}>=({todo: {id, valor}, deleteItem})=> { Retorna (    {valor}    deleteItem (id)} title="concluído" color="# 841584" acessibilidadeLabel="adicionar item de tarefa" />  );
};
estilos const=StyleSheet.create ({ todoContainer: { marginTop: 10, paddingHorizontal: 24, backgroundColor:'deepskyblue', marginLeft: 20, marginRight: 20, borderRadius: 10, borderColor:'preto', borderWidth: 1, }, todoTextContainer: { justifyContent:'center', flexDirection:'row', }, Título da seção: { fontSize: 20, fontWeight:'400', }
});

Aí está! Nosso aplicativo de tarefas React Native finalizado deve ser semelhante à imagem abaixo:

React Native Sqlite Final Todo Application

Conclusão

Neste tutorial, aprendemos como conectar um banco de dados SQLite a um aplicativo React Native e, em seguida, criamos nosso próprio aplicativo usando TypeScript.

Usamos react-native-sqlite-storage , uma biblioteca de conectores e concluímos a operação CRUD. Em seguida, combinamos essas operações com nossas atualizações de estado React e consideramos a diferença entre gerenciamento de estado simples e dados persistentes.

Espero que tenha gostado do artigo e não se esqueça de comentar quaisquer ideias e melhorias. Boa programação!

A postagem Usando SQLite com React Native apareceu primeiro em LogRocket Blog .