2019-09-03 20:13:43 -04:00
# React
2019-09-11 10:07:10 -04:00
We provide a higher-order component to connect to enhance presentational components to react to any observable (not limited to those generated by **Subspace** ).
2019-09-03 14:40:19 -04:00
2019-09-03 20:13:43 -04:00
### Usage
```js
2020-01-27 18:54:33 -04:00
import { observe } from '@embarklabs/subspace/react' ;
2019-09-03 20:13:43 -04:00
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
2019-09-06 09:28:26 -04:00
::: tip
2019-10-10 10:38:15 +09:00
This example is available in [Github ](https://github.com/embark-framework/subspace/tree/master/examples/react-example1 )
2019-09-06 09:28:26 -04:00
:::
2019-09-03 20:13:43 -04:00
#### MyComponentObserver.js
2019-09-03 14:40:19 -04:00
```js
import React from "react" ;
import ReactDOM from 'react-dom' ;
2020-01-27 18:54:33 -04:00
import { observe } from "@embarklabs/subspace/react" ;
2019-09-03 14:40:19 -04:00
const MyComponent = ({ eventData }) => {
2019-09-03 20:13:43 -04:00
// Handle initial state when no data is available
if ( ! eventData ) {
2019-09-04 15:54:23 -04:00
return < p > No data < /p>;
2019-09-03 20:13:43 -04:00
}
2019-09-03 14:40:19 -04:00
return < p > { eventData . someReturnedValue } < /p>
};
2019-09-03 20:13:43 -04:00
// MyComponent will now observe any observable prop it receives
// and update its state whenever the observable emits an event
export default observe ( MyComponent );
```
2019-09-03 14:40:19 -04:00
2019-09-03 20:13:43 -04:00
#### App.js
```js
import React , { Component } from 'react' ;
import ReactDOM from 'react-dom' ;
2020-01-27 18:54:33 -04:00
import Subspace from '@embarklabs/subspace' ;
2019-09-03 14:40:19 -04:00
2019-09-03 20:13:43 -04:00
import MyComponentObserver from './MyComponentObserver' ;
class App extends Component {
2019-09-03 14:40:19 -04:00
state = {
2019-09-03 20:13:43 -04:00
myEventObservable$ : null
2019-09-03 14:40:19 -04:00
}
2019-09-04 15:54:23 -04:00
async componentDidMount () {
const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
2020-01-27 18:54:33 -04:00
const subspace = new Subspace ( "wss://localhost:8545" ); // Use a valid provider (geth, parity, infura...)
2019-09-27 15:24:05 -04:00
await subspace . init ()
2019-09-04 15:54:23 -04:00
2019-09-27 15:24:05 -04:00
const myEventObservable$ = subspace . trackEvent ( MyContractInstance , "MyEvent" , { filter : {}, fromBlock : 1 });
2019-09-04 15:54:23 -04:00
this . setState ({ myEventObservable$ });
2019-09-03 14:40:19 -04:00
}
render () {
2019-09-03 20:13:43 -04:00
return < MyComponentObserver eventData = { this . state . myEventObservable$ } /> ;
2019-09-03 14:40:19 -04:00
}
}
2019-09-03 20:13:43 -04:00
export default App ;
2019-09-03 14:40:19 -04:00
```
2019-09-03 20:13:43 -04:00
2019-09-04 21:41:25 -04:00
::: warning Handling Contract Objects
2020-02-11 10:03:49 -04:00
The variable `MyContractInstance` is a `web3.eth.Contract` object pointing to a deployed contract address. You can use a DApp framework like [Embark ](https://embark.status.im/docs/contracts_javascript.html ) to easily import that contract instance: `import { MyContract } from './embarkArtifacts/contracts';` , or use web3.js directly (just like in the example [source code ](https://github.com/embarklabs/subspace/blob/master/examples/react/src/MyContract.js#L36-L42 ))
2019-09-04 21:41:25 -04:00
:::
2019-09-04 15:54:23 -04:00
2019-09-03 20:13:43 -04:00
#### index.js
```js
import React from 'react' ;
import ReactDOM from 'react-dom' ;
import App from './App' ;
ReactDOM . render ( < App /> , document . getElementById ( 'root' ));
2019-09-06 09:28:26 -04:00
```
2019-10-05 11:45:00 -07:00
```js
2020-01-27 18:54:33 -04:00
import { observe } from "@embarklabs/subspace/react" ;
2019-10-05 11:45:00 -07:00
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' )
);
2019-10-10 10:49:42 +09:00
```