如何在React-Native中正确使用SQLite?

问题描述 投票:0回答:1

我正在通过 EXPO 学习 React-Native。

我安装了 expo-sqlite 来初始化、插入和获取一些数据。 但我一开始就无法插入数据。 (我认为) 没有错误,但我无法到达导航功能,该功能位于等待插入功能旁边。

我不断收到警告“可能未处理的承诺拒绝(id:0)”

我该怎么办?

下面是我使用 SQLite 的代码。

import * as SQLite from 'expo-sqlite';
import { Place } from '../models/place';

const database = SQLite.openDatabase('places.db');

export function init() {
  const promise = new Promise((resolve, reject) => {
    database.transaction((tx) => {
      tx.executeSql(
        `CREATE TABLE IF NOT EXISTS places (
          id INTEGER PRIMARY KEY NOT NULL,
          title TEXT NOT NULL,
          imageUri TEXT NOT NULL,
          address TEXT NOT NULL,
          lat REAL NOT NULL,
          lng REAL NOT NULL
      )`,
        [],
        () => {
          resolve();
        },
        (_, error) => {
          reject(error);
        }
      )
    })
  })

  return promise;
}

export function insertPlace(place) {
  const promise = new Promise((resolve, reject) => {
    database.transaction((tx) => {
      tx.executeSql(
        `INSERT INTO places (title, imageUri, address, lat, lng) VALUES (?, ?, ?, ?, ?)`,
        [place.title, place.imageUri, place.address, place.lat, place.lng],
        (_, result) => {
          resolve(result);
        },
        (_, error) => {
          reject(error);
        }
      )
    })
  });

  return promise;
}

export function fetchPlaces() {
  const promise = new Promise((resolve, reject) => {
    database.transaction((tx) => {
      tx.executeSql('SELECT * FROM places', [],
        (_, result) => {
          const places = []

          for (const dp of result.rows._array) {
            places.push(new Place(dp.title, dp.imageUri, {address: dp.address, lat: dp.lat, lng: dp.lng}, dp.id))
          }
          
          resolve(places)
        },
        (_, error) => { reject(error) }
      )
    })
  });

  return promise
}

下面是我的数据模型代码,它正在安装在我的数据库代码中。

export class Place {
  constructor(title, imageUri, location, id) {
    this.title = title;
    this.imageUri = imageUri;
    this.address = location.address;
    this.location = {lat: location.lat, lng: location.lng};
    this.id = id
  }
}

下面是使用 SQLite 的其他文件。

App.js,

import { init } from './util/database';

const Stack = createNativeStackNavigator();

export default function App() {
  const [dbInitialized, setDBInitialized] = useState(false);

  useEffect(() => {
    init()
      .then(() => {
        setDBInitialized(true);
      })
      .catch((err) => {
        console.log(err)
      });
  }, [])

  if (!dbInitialized) {
    return <AppLoading />
  }

  return (
    <>
      <StatusBar style="auto" />
      <NavigationContainer>
        <Stack.Navigator screenOptions={{
          headerStyle: { backgroundColor: Colors.primary50 },
          headerTintColor: Colors.gray700,
          contentStyle: { backgroundColor: Colors.gray700 }
        }}>
          <Stack.Screen name="AllPlaces" component={AllPlaces} options={({ navigation }) => ({
            title: 'Your Favorite Places',
            headerRight: ({ tintColor }) => (
              <IconButton icon="add" size={24} color={tintColor} onPress={() => navigation.navigate('AddPlace')} />
            )
          })} />
          <Stack.Screen name="AddPlace" component={AddPlace} options={{
            title: 'Add a new Place'
          }} />
          <Stack.Screen name="Map" component={Map} />
        </Stack.Navigator>
      </NavigationContainer>
    </>
  );
}

AddPlace.js,

import PlaceForm from "../components/places/PlaceForm"

import { insertPlace } from "../util/database";

export default function AddPlace({navigation}) {
  async function createPlaceHandler(place) {
    await insertPlace(place);
    navigation.navigate('AllPlaces', {place: place});
  }

  return (
    <PlaceForm onCreatePlace={createPlaceHandler} />
  )
}

PlaceForm.js(在AddPlace.js中使用),

export default function PlaceForm({onCreatePlace}) {
  const [enteredTitle, setEnteredTitle] = useState();
  const [selectedImage, setSelectedImage] = useState();
  const [pickedLocation, setPickedLocation] = useState();

  function changeTitleHandler(enteredText) {
    setEnteredTitle(enteredText);
  }

  function takeImageHandler(imageUri) {
    setSelectedImage(imageUri);
  }

  const pickLocationHandler = useCallback((location) => {
    setPickedLocation(location);
  }, []);

  function savePlaceHandler() {
    // console.log(enteredTitle);
    // console.log(selectedImage);
    // console.log(pickedLocation);

    const placeData = new Place(enteredTitle, selectedImage, pickedLocation);
    onCreatePlace(placeData);
  }

  return (
    <ScrollView style={styles.form}>
      <View>
        <Text style={styles.label}>Title</Text>
        <TextInput style={styles.input} onChangeText={changeTitleHandler} value={enteredTitle} />
      </View>
      <ImagePicker onTakeImage={takeImageHandler} />
      <LocationPicker onPickLocation={pickLocationHandler} />
      <Button onPress={savePlaceHandler}>Add Place</Button>
    </ScrollView>
  )
}

和 AllPlaces.js

import PlacesList from "../components/places/PlacesList";

export default function AllPlace ({route}) {
  const [loadedPlaces, setLoadedPlaces] = useState([]);
  const isFocused = useIsFocused();

  useEffect(() => {
    async function loadPlaces() {
      await fetchPlaces();
    }

    if(isFocused) {
      loadPlaces();
    }
  }, [isFocused])
  return (
    <PlacesList places={loadedPlaces} />
  )
}

我曾经使用 then, catch 修复了我的 AddPlace.js。

我可以摆脱有关 Promise 的警告,但我无法使用该导航功能来导航“AllPlaces.js”。

import PlaceForm from "../components/places/PlaceForm"

import { insertPlace } from "../util/database";

export default function AddPlace({navigation}) {
  async function createPlaceHandler(place) {
    await insertPlace(place).then((result) => navigation.navigate('AllPlaces')).catch((error) => console.log(error));
  }

  return (
    <PlaceForm onCreatePlace={createPlaceHandler} />
  )
}
javascript reactjs react-native sqlite promise
1个回答
0
投票

重新启动expo应用程序并重试

© www.soinside.com 2019 - 2024. All rights reserved.