React and React-Native use the same meteor background

Keywords: Javascript MongoDB React Windows github

meteor Can quickly build pc, mobile, desktop applications.

The biggest advantage is that when the data of the database changes, it can be pushed to the front end in real time, which is very suitable for the application development of real-time display.

In react,react-native applications, only the same meteor background can be used to push data to the front end in real time.

github code address

metaor installation

windows Installation of Mete

Official recommendation chocolatey Install meteor.

  1. First from chocolatey Install chocolatey
  2. Then run choco install meteor from the command line

But meteor installation speed is very slow, after a search, found the download address installed through binary packages under Windows. https://install.meteor.com/windows Search for sources https://github.com/meteor/docs/blob/version-NEXT/long-form/alternate-windows-installation.md

OSX/Linux Installation Mete

Installation is very simple

curl https://install.meteor.com/ | sh

Verify installation

Command line input

meteor --version

Output version number to indicate successful installation

Meteor 1.8.1

mongodb installation

Installing mongodb on windows

https://www.mongodb.com/ Download Setup Pack Installation

OSX installs mongodb

brew install mongod

Or download the binary package installation

It's mongod, not mongodb

mongodb graphical interface

Recommend https://robomongo.org/ Easy to use and free of charge.

meteor DDP

react,react-native uses the same meteor background, so the meteor background is written separately from the front-end application.

This involves data interaction between background and front end in meteor, which defines a DDP protocol.

DDP protocol defines the operation of meteor background publishing data and client subscribing data.

This application uses the DDP protocol library which has been written, and the address is as follows: https://github.com/mondora/ddp.js.

Create a meteor project

meteor create --bare [project-name]

More creation parameters

meteor help create

meteor connects mongodb

The meteor project startup command is as follows:

meteor run

configure port

meteor run --port 9090

meteor connects its own mongodb

Mongodb is integrated in the meteor installation package, and the integrated mongodb is started by default.
To connect your own mongodb, you need to pass in parameters

MONGO_URL=mongodb://username:password@localhost:27017/[database-name]?authSource=admin meteor  run --port 9090

At first, the authSource=admin parameter was not added, and mongodb was not connected. After that, add it as needed.

More connection parameters

Writing meteor background

import {Meteor} from 'meteor/meteor'; 
// todo collection of mongodb 
const Todo = new Meteor.Collection('todo');
// Publish data, and the front end can call it.
Meteor.publish('todo', () => {
    return Todo.find();
});
/**
 * Define methods for front-end calls
 */
Meteor.methods({
    // Find a piece of data
    getTodo(id) {
        return Todo.findOne(id);
    },
    // Find all data
    getAllTodo() {
        return Todo.find().fetch();
    },
    // Newly added
    addTodo(item) {
        return Todo.insert(item);
    },
    // delete
    removeTodo(id) {
        return Todo.remove({_id: id});
    },
    // edit
    editTodo(item) {
        return Todo.update({_id: item.id}, {$set: item});
    },
    /**
     *
     * @param {number The current page starts from 1} current Page
     * @param {number Total number of single requests} pageSize
     */
    getPageTodo(currentPage = 1, pageSize = 10) {
        if (page < 1) {
            return null;
        }
        // meteor encapsulates the operation method of mongodb
        // For more information, see the official meteor documentation
        const total = Todo.find().count();
        const list = Todo.find(
            {},
            {
                skip: (currentPage - 1) * pageSize,
                limit: pageSize,
            }
        ).fetch();
        return {total, data: list};
    },
});
// Define the operation permissions for mongodb
// If not defined, all additions, deletions and modifications are allowed.
Todo.deny({
    // Whether to allow new operations of mongodb, return true to indicate permission, otherwise not
    insert() {
        return true;
    },
    update() {
        return true;
    },
    remove() {
        return true;
    },
});

export default Todo;

Front end call

Define higher-order components

For code reuse, high-order components are defined and react and react-native can be shared

// meteor.js
import React, {Component} from 'react';
import DDP from 'ddp.js';
/**
 * meteor Connection options
 */
const meteorOptions = {
  endpoint: 'ws://192.168.31.121:9090/websocket', //react-native does not support localhost,127.0.0.1. Please replace it with your IPv4 address.
  SocketConstructor: WebSocket,
  reconnectInterval: 10000,// Reconnect interval
  autoConnect: true,// Whether to connect automatically or not
  autoReconnect: true,// Whether to automatically reconnect
};
const PUBLIC_EVENTS = [
  // 'ready',
  // 'nosub',
  'added',
  'changed',
  'removed',
  // 'result',
  // 'updated',
  // 'error',
];
export default (WrapperComponent, {collectionName, methodName}) => {
  class MeteorWrapper extends Component {
    ddp = new DDP(meteorOptions);
    lockRequest = false
    recordSubscriptions = {};
    state = {
      meteorList: [],
      initOver: false,
    };

    componentDidMount() {
      if (!this.ddp) {
        console.error(`Data push is not connected to the server!`);
        return;
      }
      // Add a subscription
      this.addSubscription();
    }

    componentWillUnmount() {
      // unsubscribe
      this.removeSubscription();
      // Disconnect
      this.ddp.disconnect();
    }

    getDataResult() {
      // Prevent too many initialization requests
      if (this.lockRequest) {
        return
      }
      this.lockRequest = true
      const {ddp} = this;
      const self = this;
      /**
       * Call the method defined in the background, pass the array parameters in the front end, and accept the list parameters in the meteor background.
       */
      ddp.method(methodName, [1, 10]);
      ddp.on('result', data => {
        const {result} = data;
        console.log(data);
        self.setState({
          meteorList: result,
          initOver: true,
        });
        self.lockRequest = false
      });
    }

    componentDidCatch(error, info) {
      console.error(error, info);
    }

    addSubscription() {
      if (!collectionName) {
        console.error('mongodb collection Empty!');
        return;
      }
      const {ddp} = this;
      const self = this;
      // Subscription data
      self.recordSubscriptions[collectionName] = ddp.sub(collectionName);
      PUBLIC_EVENTS.forEach(event => {
        ddp.on(event, () => {
          console.log(event)
          self.getDataResult();
        });
      });
      ddp.on('error', error => {
        console.error(`Server Push Data Error,Error message: ${error}`)
      });
      ddp.on('ready', () => {
        self.getDataResult();
      });
    }

    removeSubscription() {
      this.ddp.unsub(this.recordSubscriptions[collectionName]);
    }

    render() {
      return <WrapperComponent {...this.props} {...this.state} />;
    }
  }

  return MeteorWrapper;
};

react usage example

import React, {Component} from 'react';
import {List, Skeleton} from 'antd';
import './App.css';
import MeteorWrapper from './meteor'

function App(props) {
  const {meteorList = [], initOver} = props
  return (
    <div className="App">
      <List
        itemLayout="horizontal"
        dataSource={meteorList}
        renderItem={item => (
          <List.Item key={item.id}>
            <Skeleton loading={!initOver} active avatar>
              <List.Item.Meta
                title={item.name}
                description={item.desc}
              />
            </Skeleton>

          </List.Item>
        )}
      />
    </div>
  );
}

export default MeteorWrapper(App, {
  collectionName:'todo',
  methodName:'getAllTodo'
})

react-native usage example

import React  from 'react';
import {StyleSheet, Text, View, FlatList} from 'react-native';
import MeteorWrapper from './meteor'

function App(props) {
  const {meteorList = [], initOver} = props
  return (
    <View style={styles.container}>
      <FlatList
        data={meteorList}
        renderItem={({item}) => (
          <View style={styles.item}>
            <View style={styles.name}><Text>{item.name}</Text></View>
            <View style={styles.desc}><Text>{item.desc}</Text></View>
          </View>)}
      />
    </View>
  );
}

export default MeteorWrapper(App, {
  collectionName:'todo',
  methodName:'getAllTodo'
})
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    fontSize: 14,
    lineHeight: 2,
  },
  item: {
    padding: 10,
    borderColor: '#ccc',
    borderBottomWidth: 1,
    borderStyle: 'solid',
  },
  name: {
    color: '#000',
    fontWeight: "900",
    fontSize: 24
  },
  desc: {
    color: '#666'
  }
});

Open remote debugging

Run command

adb shell input keyevent 82

Click dev set
Then click Debug server host & port for device
Set it to 127.0.0. 1:8081

Run again

adb shell input keyevent 82

Click Debug js remote and the debug page will pop up automatically.

IOS Running Error Reporting

The error message is as follows, please check it. Resolve React-Native Mac 10.14.4 Running Error Failed to BuiliOS Project

error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by opening reactNative.xcodeproj

Posted by djKale on Fri, 17 May 2019 22:57:19 -0700