v1.2.0
Support for React 16's New Context API ⚛️
Fixes #20
This release adds a new DrizzleContext object that relies on the new React Context API. It uses the Render Prop pattern, which has become the new gold standard for sharing things between components in React.
We have also bumped React dependency to v16.4.2, but we retain the old API for compatibility.
Here's how it works...
1. Setup the Provider
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
// Setup Drizzle
import { Drizzle, generateStore } from "drizzle";
import { DrizzleContext } from "drizzle-react";
import SimpleStorage from "./contracts/SimpleStorage.json";
const options = { contracts: [SimpleStorage] };
const drizzleStore = generateStore(options);
const drizzle = new Drizzle(options, drizzleStore);
// Pass in the drizzle instance into the provider
ReactDOM.render(
<DrizzleContext.Provider drizzle={drizzle}>
<App />
</DrizzleContext.Provider>,
document.getElementById("root")
);2. Setup the Consumer
Then, in any child component of the app, we can access the drizzle instance as well as the drizzleState.
In our render tree, we use the DrizzleContext.Consumer component to get access to Drizzle. This component will call its function child with the following object:
const drizzleContext = {
drizzle, // this is the drizzle instance (use this to call `cacheCall` and `cacheSend`)
drizzleState, // this is the entire Drizzle state, it will always be up-to-date
initialized // this boolean value will indicate when Drizzle is ready
}Please see the following example:
import React from "react";
import { DrizzleContext } from "drizzle-react";
export default () => (
<DrizzleContext.Consumer>
{drizzleContext => {
const { drizzle, drizzleState, initialized } = drizzleContext;
if (!initialized) {
return "Loading...";
}
return (
<MyDrizzleApp drizzle={drizzle} drizzleState={drizzleState} />
);
}}
</DrizzleContext.Consumer>
)3. Reference: <MyDrizzleApp />
For reference, here is an example of what <MyDrizzleApp /> might look like:
import React from "react";
export default class MyDrizzleApp extends React.Component {
state = { dataKey: null };
componentDidMount() {
const { drizzle } = this.props;
const contract = drizzle.contracts.SimpleStorage;
// get and save the key for the variable we are interested in
const dataKey = contract.methods["storedData"].cacheCall();
this.setState({ dataKey });
}
render() {
const { SimpleStorage } = this.props.drizzleState.contracts;
const storedData = SimpleStorage.storedData[this.state.dataKey];
return <p>My stored value: {storedData && storedData.value}</p>;
}
}Caveat
The drizzleState will keep refreshing, if you don't want unnecessary re-renders, then you'll need to put in your own logic to compare the slice of state you are interested in. It's also advisable to use PureComponent wherever possible to mitigate this.