Sử dụng Realm Database trong React Native (ok)
https://github.com/codegym-vn/react-database-realm
Last updated
Was this helpful?
https://github.com/codegym-vn/react-database-realm
Last updated
Was this helpful?
C:\Users\Administrator\Desktop\Apps\index.js
import { registerRootComponent } from 'expo';
import App from './App';
registerRootComponent(App);
C:\Users\Administrator\Desktop\Apps\App.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import HomePage from "./src/components/HomePage";
export default function App() {
return (
<View style={styles.container}>
<HomePage />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
C:\Users\Administrator\Desktop\Apps\src\components\Header.js
import React, { Component } from 'react'
import { View, Text, StyleSheet } from 'react-native'
class Header extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>ToDo App</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
backgroundColor: 'green',
justifyContent: 'center'
},
text: {
padding: 10,
color: '#fff',
textAlign: 'center',
fontSize: 16,
}
})
export default Header
C:\Users\Administrator\Desktop\Apps\src\components\HomePage.js
import React, { Component } from 'react'
import { View, StyleSheet } from 'react-native'
import ListTasks from "./ListTasks";
import FormCreate from "./FormCreate";
import { getListTasks, addTask, removeTask, toggleTask } from '../services/StorageServices'
class HomePage extends Component {
state = {
tasks: [],
loading: false
}
componentDidMount() {
this._fetchListTasks()
}
_fetchListTasks = () => {
this.setState({ loading: true })
getListTasks().then(tasks => {
this.setState({
loading: false,
tasks,
})
}).catch(error => {
console.error(error)
this.setState({ loading: false })
})
}
_handleOnCreate = name => {
addTask(name)
.then(tasks => {
this.setState({
tasks
})
})
}
_handleOnRemove = task => {
removeTask(task)
.then((currentTasks) => {
this.setState({
tasks: currentTasks
})
})
}
_handleToggleTask = (id) => {
toggleTask(id)
.then((tasks) => {
this.setState({
tasks,
})
})
}
render() {
const { tasks } = this.state
return (
<View style={styles.container}>
<FormCreate onCreate={this._handleOnCreate}/>
<ListTasks onToggle={this._handleToggleTask} onRemove={this._handleOnRemove} tasks={tasks}/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
flexDirection: 'column',
width: '100%',
backgroundColor: '#eee'
}
})
export default HomePage;
C:\Users\Administrator\Desktop\Apps\src\components\ListTasks.js
import React, { Component } from 'react'
import { View, ScrollView, StyleSheet } from 'react-native'
import PropTypes from 'prop-types'
import TaskItem from "./TaskItem"
class ListTasks extends Component {
render() {
const { tasks, onRemove, onToggle } = this.props
return (
<View style={styles.container}>
<ScrollView>
{
tasks.map((task, index) => {
return (
<TaskItem key={index} index={index} onToggle={onToggle} onRemove={onRemove} task={task}/>
)
})
}
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
paddingLeft: 10,
paddingRight: 10,
}
})
ListTasks.propTypes = {
tasks: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
onRemove: PropTypes.func.isRequired,
onToggle: PropTypes.func.isRequired,
}
export default ListTasks
C:\Users\Administrator\Desktop\Apps\src\components\TaskItem.js
import React, { Component } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import moment from 'moment';
class TaskItem extends Component {
state = {
now: Date.now()
}
_interval = null
componentDidMount() {
const ONE_MINUTE = 60 * 1000
this._interval = setInterval(this._refreshCreatedTime, ONE_MINUTE)
}
componentWillUnmount() {
this._interval && clearInterval(this._interval)
}
_refreshCreatedTime = () => {
this.setState({
now: Date.now()
})
}
_handlePressRemove = () => {
this.props.onRemove(this.props.task)
}
_handleCompleteTask = () => {
this.props.onToggle(this.props.task)
}
render() {
const { task } = this.props
const { name, completed, created } = task
const { now } = this.state
const createdTime = moment(created).from(moment(now))
return (
<View style={[styles.container, completed ? styles.completed : {}]}>
<View style={styles.left}>
<Button
color={completed ? 'green' : 'gray'}
onPress={this._handleCompleteTask}
title='✓'/>
<View style={styles.content}>
<TextonPress={this._handleCompleteTask}style={[styles.name]}>{name}</Text>
<Text style={styles.created}>{createdTime}</Text>
</View>
</View>
<Buttoncolor='red' onPress={this._handlePressRemove} title="✕"/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#fff',
marginBottom: 10,
paddingTop: 5,
paddingBottom: 5,
flexWrap: 'wrap'
},
content: {
paddingRight: 10
},
name: {
fontSize: 16,
color: '#333',
marginBottom: 5,
},
created: {
color: '#999',
fontSize: 10
},
completed: {
opacity: 0.5
},
left: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center'
}
})
TaskItem.propTypes = {
task: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
onRemove: PropTypes.func.isRequired,
onToggle: PropTypes.func.isRequired,
}
export default TaskItem
C:\Users\Administrator\Desktop\Apps\src\components\FormCreate.js
import React, { Component } from 'react';
import { View, TextInput, Button, StyleSheet, Alert } from 'react-native';
import PropTypes from 'prop-types';
class FormCreate extends Component {
state = {
text: ''
}
_handleChangeText = text => {
this.setState({
text,
})
}
_handlePressAdd = () => {
this._submit()
}
_handleSubmitText = () => {
this._submit()
}
_submit = () => {
const { text } = this.state
if (!text) {
return Alert.alert('Please enter your task!', () => {
//Focus on input text
})
}
this.props.onCreate(text)
this.setState({
text: ''
})
}
render() {
const { text } = this.state
return (
<View style={styles.container}>
<View style={styles.form}>
<TextInput placeholder="Your task today" style={styles.textInput} value={text} onSubmitEditing={this._handleSubmitText} onChangeText={this._handleChangeText}/>
<Button color='#333' title="Add" onPress={this._handlePressAdd}/>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
marginTop: 34,
width: '100%',
},
form: {
padding: 10,
},
textInput: {
fontSize: 14,
padding: 10,
backgroundColor: '#fff',
borderRadius: 20,
}
})
FormCreate.propTypes = {
onCreate: PropTypes.func.isRequired,
}
export default FormCreate
C:\Users\Administrator\Desktop\Apps\src\services\StorageServices.js
import realm from './../realm';
export const getListTasks = () => {
const tasks = realm.objects('Task')
return Promise.resolve(tasks)
}
export const addTask = (name) => {
if (!name) {
return Promise.reject('Task name is empty')
}
const data = {
created: new Date(),
name,
completed: false
}
const tasks = realm.objects('Task')
return new Promise((resolve, reject) => {
realm.write(() => {
realm.create('Task', data)
resolve(tasks)
})
})
}
export const removeTask = (task) => {
const tasks = realm.objects('Task')
return new Promise(resolve => {
realm.write(() => {
realm.delete(task)
resolve(tasks)
})
})
}
export const toggleTask = (task) => {
const tasks = realm.objects('Task')
return new Promise(resolve => {
realm.write(() => {
task.completed = !task.completed
resolve(tasks)
})
})
}
C:\Users\Administrator\Desktop\Apps\src\realm.js
import Realm from 'realm';
const TaskSchema = {
name: 'Task',
properties: {
name: 'string',
created: 'date',
completed: 'bool'
}
}
export default new Realm({
schema: [TaskSchema]
})
C:\Users\Administrator\Desktop\Apps\package.json
{
"main": "index.js",
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"web": "expo start --web",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"@material-ui/core": "^4.11.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/bottom-tabs": "^5.8.0",
"@react-navigation/drawer": "^5.9.0",
"@react-navigation/native": "^5.7.3",
"@react-navigation/stack": "^5.9.0",
"expo": "~38.0.9",
"expo-splash-screen": "^0.5.0",
"expo-status-bar": "^1.0.0",
"expo-updates": "~0.2.10",
"moment": "^2.27.0",
"prop-types": "^15.7.2",
"react": "~16.11.0",
"react-dom": "~16.11.0",
"react-native": "~0.62.2",
"react-native-gesture-handler": "^1.7.0",
"react-native-material-ui": "^1.30.1",
"react-native-paper": "^4.0.1",
"react-native-popup-dialog": "^0.18.3",
"react-native-reanimated": "^1.13.0",
"react-native-safe-area-context": "^3.1.7",
"react-native-screens": "^2.10.1",
"react-native-swipeout": "^2.3.6",
"react-native-unimodules": "~0.10.1",
"react-native-web": "~0.11.7",
"react-redux": "^7.2.1",
"realm": "^6.1.0",
"redux": "^4.0.5",
"redux-form": "^8.3.6"
},
"devDependencies": {
"@babel/core": "~7.9.0",
"babel-jest": "~25.2.6",
"jest": "~25.2.6",
"react-test-renderer": "~16.11.0"
},
"jest": {
"preset": "react-native"
},
"private": true
}