I am suffering from problems with using sqlite in React Native.
If I click a button on the searchscreen, the screen changes. I tried to load and display data in a new screen(which is Bookmark), but it doesn’t work properly.
It renders nothing in the beginning. When I click save button, it shows data. But I want to render immediately.
this is my code:
/*This is SearchScreen.js*/
import React, { useState } from "react";
import {View, Text, StyleSheet, TouchableOpacity, FlatList, ScrollView} from 'react-native';
import { SafeAreaView } from "react-native-safe-area-context";
import SearchBar from "./SearchBar";
import Search from "./mode/Search";
import Bookmark from "./mode/Bookmark";
import Expiration from "./mode/Expiration";
const componentMap = {
Search,
Expiration,
Bookmark,
};
function renderText(mode){
switch(mode){
case 'Expiration':
return '유통기한';
case 'Bookmark':
return '즐겨찾기';
default:
return '';
}
}
const SearchScreen = () => {
const [searchText, setSearchText] = useState("");
const [mode, setMode] = useState('Search');
const renderScreen = () => {
const Component = componentMap[mode];
return <Component/>;
};
return(
<SafeAreaView style={{flex: 1,}}>
<SearchBar searchText={searchText} setSearchText={setSearchText} onSubmit={()=>{setMode('Search')}}/>
<Text style={styles.recommendText} >레시피 추천 </Text>
<View style={styles.buttonview}>
{Object.keys(componentMap).map(type => (type!=='Search'?
<TouchableOpacity
key={type}
style={[
styles.switch,
{
backgroundColor:
mode === type ? '#e1615b' : '#EFEFEF',
},
]}
onPress={() => setMode(type)}
>
<Text style={{color: mode===type? 'white': '#1A1A1A'}}>{renderText(type)}</Text>
</TouchableOpacity>
: null
))}
</View>
{renderScreen()}
</SafeAreaView>
)
}
const styles = StyleSheet.create({
button:{
margin: 5,
padding: 5
},
recommendText: { marginTop: 15, marginLeft: 25, marginBottom: 5, fontSize: 20, fontWeight: "700" },
buttonview: { flexDirection: "row", paddingLeft: 18, margin: 5 },
switch: {
alignItems: 'center',
marginVertical: 2,
marginHorizontal: 2,
paddingVertical: 8,
paddingHorizontal: 12,
borderRadius: 6
},
})
export default SearchScreen;
/*This is Bookmark.js*/
import { useIsFocused } from "@react-navigation/native";
import React, { useEffect, useState } from "react";
import { Text, ScrollView } from "react-native";
import SQLite from "react-native-sqlite-storage";
import Thumbnail from "../Thumbnail";
var db = SQLite.openDatabase({ name: 'recipe.db', createFromLocation:"~www/recipe.db"});
var recipe_db = SQLite.openDatabase({ name: 'db.sqlite', createFromLocation:"~www/db.sqlite"});
const Bookmark = () => {
//const isFocused = useIsFocused()
const [isLoading, setIsLoading] = useState(true)
const [ingList, setIngList] = useState([]);
const [recipeList, setRecipeList] = useState({
name: [],
id: []
});
const [thumbnailList, setthumbnailList] = useState([])
useEffect(() => {
getbookmark();
getrecipe();
}, [])
useEffect(() => {
searchRecipe();
},[]);
const getbookmark = () => {
db.transaction((tx) => {
tx.executeSql(
'SELECT name FROM ingredients WHERE bookmark=1',
[],
(tx, results) => {
var bookmarks = [];
for (let i = 0; i < results.rows.length; ++i) {
bookmarks.push(results.rows.item(i).name);
}
setIngList(bookmarks);
}
);
});
}
const getrecipe = () => {
let query = '...**query';
for (let i = 0; i < ingList.length; ++i) {
query = query + " trim(A.ingredient_name) = " + "'" + ingList[i].trim() + "'";
if (i != ingList.length - 1) {
query = query + " OR";
}
}
query = query + "**query";
console.log('query: ', query)
recipe_db.transaction((tx) => {
tx.executeSql(
query,
[],
(tx, results) => {
var name = [];
var id = [];
for (let i = 0; i < (results.rows.length > 5 ? 5 : results.rows.length); ++i) {
name.push(results.rows.item(i).name);
id.push(results.rows.item(i).recipe_id);
console.log(results.rows.item(i))
}
setRecipeList({ name: name, id: id })
}
);
});
}
const searchRecipe = () => {
getThumbnail(recipeList)
}
const maxResults = 1;
function getThumbnail(Array){
_getThumbnail(Array.name)
}
async function _getThumbnail(query) {
let videoList = [];
for (const q of query) {
console.log('q is', q)
const optionParams = {
q: q,
part: "snippet",
key: YOUTUBE_API_KEY,
type: "video",
maxResults: maxResults,
regionCode: "KR",
videoDuration: "short"
};
optionParams.q = encodeURI(optionParams.q);
var url = "https://www.googleapis.com/youtube/v3/search?";
for (var option in optionParams) {
url += option + "=" + optionParams[option] + "&";
}
const options = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
};
await fetch(url, options)
.then((response) => response.json())
.then((resData) => {
for (var i = 0; i < maxResults; i++) {
if (resData['items'][i]) {
const vId = resData['items'][i]['id']['videoId'];
const imguri = 'https://i.ytimg.com/vi/' + vId + '/hqdefault.jpg';
const name = q;
videoList.push({ vId, imguri, name });
}
}
console.log('videolist: ',videoList)
setthumbnailList(videoList)
})
.catch((error) => {
console.log(error);
})
.finally(()=>{
}
)
}
setIsLoading(false)
}
return (
<>
<Text>Bookmark</Text>
<ScrollView>
{(!isLoading) ?
thumbnailList.map((thumbnail, index) => {
return (<Thumbnail key={index} vId={thumbnail.vId} title={thumbnail.name} rId={recipeList[index]} imguri={thumbnail.imguri} />)
})
: <Text>Loading</Text>
}
</ScrollView>
</>
)
}
export default Bookmark;
Thank you for your help
2
Answers
Try this instead of
isLoading
Try to write setLoading(false) below the setTumbnail() when fetch successfull.