2020-03-09 11:31:29 -04:00

3.3 KiB

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);

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

::: tip 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);

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;

::: warning 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'));
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')
);