React

We provide a higher-order component to connect to enhance presentational components to react to any observable (not limited to those generated by Subspace).

Usage

import { observe } from '@embarklabs/subspace/react';

const ObserverComponent = observe(WrappedComponent);
1
2
3

This enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.

Example

This example is available in Github

MyComponentObserver.js

import React from "react";
import ReactDOM from 'react-dom';
import {observe} from "@embarklabs/subspace/react";

const MyComponent = ({eventData}) => {
  // Handle initial state when no data is available
  if (!eventData) {
    return <p>No data</p>;
  }
  
  return <p>{eventData.someReturnedValue}</p>
};

// MyComponent will now observe any observable prop it receives
// and update its state whenever the observable emits an event
export default observe(MyComponent);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

App.js

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import Subspace from '@embarklabs/subspace';

import MyComponentObserver from './MyComponentObserver';

class App extends Component {
  state = {
    myEventObservable$: null
  }

  async componentDidMount() {
    const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance

    const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)
    await subspace.init()
    
    const myEventObservable$ = subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });
    this.setState({ myEventObservable$ });
  }

  render() {
    return <MyComponentObserver eventData={this.state.myEventObservable$} />;
  }
}

export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Handling Contract Objects

The variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address. You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
1
2
3
4
5
import { observe } from "@embarklabs/subspace/react";

const ProductComponent = ({ maxRating, minRating, averageRating }) => {
  return <ul>
    <li><b>minimum rating: </b> {minRating}</li>
    <li><b>maximum rating: </b> {maxRating}</li>
    <li><b>average rating: </b> {averageRating}</li>
  </ul>;
};

const ReactiveProductComponent = observe(ProductComponent);

const Product = subspace.contract({abi, address});
const rating$ = Product.events.Rating.track().map("rating").pipe(map(x => parseInt(x)));

ReactDOM.render(
  <ReactiveProductComponent
    maxRating={rating$.pipe($max())}
    minRating={rating$.pipe($min())}
    averageRating={rating$.pipe($average())}
  />,
  document.getElementById('hello-example')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23