React Native初始数据库

时间:2017-06-07 14:31:41

标签: javascript android ios react-native

我想开发一个React Native应用程序,我想在本地存储一些格式的数据:

[
  {
    "id": 1,
    "text": "Lorem ipsum",
    "viewed": false
  },
  {
    "id": 2,
    "text": "Second lorem",
    "viewed": false
  },
  {
    "id": 3,
    "text": "Last lorem",
    "viewed": false
  }
]

我希望用户首次下载应用时此数据可用。然后根据用户的导航,db中的相应数据会将viewed标志更改为true。当用户在下一个版本上更新应用程序时,这必须是持久的。

有关如何实现这一目标的任何提示/想法?

目前我正在研究Realm.io,但我不确定这是否适合我。

2 个答案:

答案 0 :(得分:1)

您可以像这样使用AsyncStorage

const data = [
  {
    "id": 1,
    "text": "Lorem ipsum",
    "viewed": false
  },
  {
    "id": 2,
    "text": "Second lorem",
    "viewed": false
  },
  {
    "id": 3,
    "text": "Last lorem",
    "viewed": false
  }
]

try {
  await AsyncStorage.setItem(
    'SOME_KEY', JSON.stringify(data)
  );
} catch (error) {
  // Handle error 
}

稍后,如果您想要获取/更改,您可以执行以下操作:

AsyncStorage.getItem('SOME_KEY', (err, result) => {
  console.log(JOSN.parse(result));
});

答案 1 :(得分:0)

如果数据超过pouchDb建议选项。

您可以使用

进行安装
npm install pouchdb-react-native --save

简单演示

import PouchDB from 'pouchdb-react-native'
const db = new PouchDB('mydb')

// use PouchDB
db.get('4711')
  .then(doc => console.log(doc))

推进演示

'use strict'

import React from 'react'
import {
  AsyncStorage,
  ListView,
  Navigator,
  StyleSheet,
  Text,
  TextInput,
  TouchableHighlight,
  View
} from 'react-native'

import ActionButton from 'react-native-action-button'
import PouchDB from 'pouchdb-react-native'

const localDB = new PouchDB('myDB')
console.log(localDB.adapter)

AsyncStorage.getAllKeys()
  .then(keys => AsyncStorage.multiGet(keys))
  .then(items => console.log('all pure Items', items))
  .catch(error => console.warn('error get all Items', error))

export default React.createClass({
  getInitialState () {
    const updateDocs = () => {
  localDB.allDocs({include_docs: true, limit: null})
    .then(result => {
      const items = result.rows.map(row => row.doc)
      const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1.id !== r2.id})
      this.setState({
        dataSource: ds.cloneWithRows(items),
        count: items.length
      })
    })
    .catch(error => console.warn('Could not load Documents', error, error.message))
}

localDB.changes({since: 'now', live: true})
  .on('change', () => updateDocs())

updateDocs()

return {
  dataSource: null,
  syncUrl: 'http://localhost:5984/test'
}
  },
  render () {
const renderScene = (route, navigator) => (
  <View style={{flex: 1, marginTop: 20, backgroundColor: '#FFFFFF'}}>
    {route.render()}
  </View>
)

const renderMain = () => {
  const insertAttachment = () => {
    const doc = {
      'title': 'with attachment',
      '_attachments': {
        'att.txt': {
          'content_type': 'text/plain',
          'data': 'TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS' +
                  'BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=='
        }
      }
    }

    localDB.post(doc)
      .then(result => console.log('save.attachment', result))
      .catch(error => console.warn('save.attachment.error', error, error.message, error.stack))
  }

  const insertRecords = count => {
    for (let index = 0; index < count; index++) {
      localDB.post({
        text: `Record ${index}/${count}`
      })
    }
  }

  const destroy = count => {
    localDB.destroy()
      .then(() => console.log('destroyed'))
      .catch(error => console.warn('destroyed', error))
  }

  const { dataSource } = this.state

  const renderSeparator = (sectionID, rowID) => (
    <View
      key={rowID}
      style={{borderColor: '#969A99', borderBottomWidth: StyleSheet.hairlineWidth}} />
  )

  const renderRow = (row) => {
    const updateItem = () => {
      const newRow = {...row}
      newRow.clickCount = newRow.clickCount ? newRow.clickCount + 1 : 1

      localDB.put(newRow)
        .then(result => console.log('Updated Item', result))
        .catch(error => console.warn('Error during update Item', error))
    }

    return (
      <TouchableHighlight onPress={updateItem}>
        <View key={row._id}>
          <Text style={{fontWeight: 'bold'}}>{row._id}</Text>
          <Text>{JSON.stringify(row, null, 4)}</Text>
        </View>
      </TouchableHighlight>
    )
  }

  const renderList = () => (
    <ListView
      dataSource={dataSource}
      renderRow={renderRow}
      renderSeparator={renderSeparator}
      enableEmptySections />
  )

  return (
    <View style={{flex: 1}}>
      <View>
        {!!this._sync && <Text style={{fontWeight: 'bold'}}>{this.state.syncUrl}</Text>}
        <Text style={{fontWeight: 'bold'}}>Count: {this.state.count}</Text>
      </View>
      <View
        style={{borderColor: '#969A99', borderBottomWidth: StyleSheet.hairlineWidth}} />
      {!dataSource
        ? (<Text>Loading...</Text>)
        : renderList()
      }
      <ActionButton buttonColor='#78B55E'>
        <ActionButton.Item
          buttonColor='#005BFF'
          title='Destroy Database'
          onPress={destroy}>
          <Text>destroy</Text>
        </ActionButton.Item>
        <ActionButton.Item
          buttonColor='#005BFF'
          title='Insert Attachments'
          onPress={insertAttachment}>
          <Text>attach</Text>
        </ActionButton.Item>
        <ActionButton.Item
          buttonColor='#005BFF'
          title='Insert 250 Records'
          onPress={() => insertRecords(250)}>
          <Text>insert</Text>
        </ActionButton.Item>
        <ActionButton.Item
          buttonColor='#005BFF'
          title='Sync'
          onPress={() => this._navigator.push({name: 'Sync', render: renderSync})}>
          <Text>sync</Text>
        </ActionButton.Item>
        <ActionButton.Item
          buttonColor='#005BFF'
          title='Add Item'
          onPress={() => this._navigator.push({name: 'AddItem', render: renderAddItem})}>
          <Text>+</Text>
        </ActionButton.Item>
      </ActionButton>
    </View>
  )
}

const renderButton = (text, onPress) => {
  return (
    <TouchableHighlight
      onPress={onPress}
      style={{
        flexDirection: 'column',
        paddingTop: 3,
        paddingBottom: 3,
        marginLeft: 10,
        marginRight: 10,
        backgroundColor: '#78B55E',
        borderRadius: 5
      }}>
      <Text
        style={{
          flex: 1,
          fontSize: 18,
          fontWeight: 'bold',
          color: '#FFFFFF',
          paddingLeft: 10,
          paddingRight: 10,
          paddingTop: 2,
          alignSelf: 'center'
        }}>
        {text}
      </Text>
    </TouchableHighlight>
  )
}

const renderSync = () => {
  const addSync = () => {
    if (this._sync) {
      this._sync.cancel()
      this._sync = null
    }

    if (this.state.syncUrl) {
      const remoteDb = new PouchDB(this.state.syncUrl, {ajax: {cache: false}})
      this._sync = PouchDB.sync(localDB, remoteDb, {live: true, retry: true})
        .on('error', error => console.error('Sync Error', error))
        .on('change', info => console.log('Sync change', info))
        .on('paused', info => console.log('Sync paused', info))
    }

    this._navigator.pop()
  }

  return (
    <View style={{flex: 1}}>
      <TextInput
        style={{
          height: 40,
          lineHeight: 40,
          fontSize: 16,
          paddingLeft: 10,
          paddingRight: 10
        }}
        autoFocus
        keyboardType='url'
        clearButtonMode='always'
        placeholder='enter URL'
        onChangeText={(text) => this.setState({syncUrl: text})}
        value={this.state.syncUrl} />
      {renderButton('Add Sync', addSync)}
    </View>
  )
}

const renderAddItem = () => {
  const addItem = () => {
    localDB.post(JSON.parse(this.state.newItem))
      .then(result => {
        this.setState({newItem: ''})
        this._navigator.pop()
      })
      .catch(error => console.error('Error during create Item', error, error.message))
  }

  return (
    <View style={{flex: 1}}>
      <TextInput
        style={{
          height: 340,
          lineHeight: 40,
          fontSize: 16,
          paddingLeft: 10,
          paddingRight: 10
        }}
        autoFocus
        clearButtonMode='always'
        multiline
        placeholder='JSON Object here'
        onChangeText={(text) => this.setState({newItem: text})}
        value={this.state.newItem} />
      {renderButton('Add Item', addItem)}
    </View>
  )
}

return (
  <View style={{flex: 1}}>
    <Navigator
      ref={navigator => { this._navigator = navigator }}
      renderScene={renderScene}
      initialRoute={{name: 'Main', render: renderMain}}
    />
  </View>
)
  }
})