大家好!
在WatermelonDB 文档中,您可以使用withObservables()
方法使组件反应,每次数据更改时,它都会更新或重新渲染您的组件。
在我的代码中
我有已存储到 WatermelonDB 的基本用户数据,当我是console.log()
该数据时的结果是:
{
"__changes": {
"_isScalar": false,
"_value": [Circular],
"closed": false,
"hasError": false,
"isStopped": false,
"observers": [],
"thrownError": null
},
"_hasPendingDelete": false,
"_hasPendingUpdate": false,
"_isCommitted": true,
"_isEditing": false,
"_raw": {
"_changed": "",
"_status": "created",
"city": "NY City", // The data that I added
"id": "rddcv3ttt9s03jel", // The data that I added
"name": "John Doe", // The data that I added
"user_id": 0 // The data that I added
},
"_subscribers": [],
"collection": {
"_cache": {
"map": [Map],
"recordInsantiator": [Function anonymous],
"tableName": "user"
},
"_subscribers": [],
"changes": {
"_isScalar": false,
"closed": false,
"hasError": false,
"isStopped": false,
"observers": [Array],
"thrownError": null
},
"database": {
"_actionQueue": [ActionQueue],
"_actionsEnabled": true,
"_isBeingReset": false,
"_resetCount": 0,
"_subscribers": [Array],
"adapter": [DatabaseAdapterCompat],
"collections": [CollectionMap],
"schema": [Object]
},
"modelClass": [Function User]
}
}
使用withObservables()
方法我可以显示该数据,这是我的代码:
import React, {useEffect, useState} from 'react';
import {Button, Layout} from '@ui-kitten/components';
import WATERMELON from '../models';
import util from '../utils';
import {View} from 'react-native';
import withObservables from '@nozbe/with-observables';
import {Text} from '../components/Helper';
const enhance = withObservables(['user'], props => {
return {
user: props.user,
};
});
const UserBasicInfo = enhance(props => {
// Successfully displaying the data but not Reactive
return (
<>
<Text>{props.user.name}</Text> {/* John Doe */}
<Text>{props.user.city}</Text> {/* NY City */}
</>
);
});
const TestScreen = props => {
const [user, setUser] = useState(null);
useEffect(() => {
(async () => {
await WATERMELON.action(async () => {
const user_collection = WATERMELON.collections.get('user');
const fetch_userdata = await user_collection.find('rddcv3ttt9s03jel');
console.log(fetch_userdata);
setUser([fetch_userdata]);
});
})();
}, []);
return (
<Layout>
<View>
<Text>Hello Test Screen!</Text>
{user !== null && <UserBasicInfo user={user} />}
<Button
onPress={async () => {
await WATERMELON.action(async () => {
const user_collection = WATERMELON.collections.get('user');
const userd = await user_collection.find('rddcv3ttt9s03jel');
await userd.update(user => {
// Just want to change the city
// And it's just fine BUT not reactive :(
user.city = 'Chicago';
});
});
}}
>
Press It
</Button>
</View>
</Layout>
);
};
export default TestScreen;
我的模型/user.model.js
import {Model} from '@nozbe/watermelondb';
import {field} from '@nozbe/watermelondb/decorators';
export default class User extends Model {
static table = 'user';
@field('name') name;
@field('city') city;
}
我的模型/index.js 文件
import fs from 'react-native-fs';
import {Database} from '@nozbe/watermelondb';
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
import schema from '../schema/watermelon.schema';
import userModel from './user.model';
import customerModel from './customer.model';
// First, create the adapter to the underlying database:
const adapter = new SQLiteAdapter({
schema,
dbName: `${fs.DocumentDirectoryPath}/restronic`, // optional database name or file system path
// migrations, // optional migrations
synchronous: true, // synchronous mode only works on iOS. improves performance and reduces glitches in most cases, but also has some downsides - test with and without it
// experimentalUseJSI: true, // experimental JSI mode, use only if you're brave
});
// Then, make a Watermelon database from it!
const db = new Database({
adapter,
modelClasses: [userModel, customerModel],
actionsEnabled: true,
});
export default db;
我不知道我的代码有什么问题,我只是按照文档中的教程进行操作,但它仍然没有反应:(
更新
我尝试使用.subscribe()
方法,但仍然没有反应,更糟糕的是,当我在该方法中时,它没有重新渲染组件,当我在setState()
该方法中尝试时,该方法运行良好console.log()
const UserBasicInfo = props => {
const [state, setState] = useState(props.user);
useEffect(() => {
const subscription = props.user.subscribe(newVal => {
// Not re-rendering the component
setState(newVal);
});
return () => subscription.unsubscribe();
});
return <>{state !== null && <Text>{state.name}</Text>}</>;
};