* add @waku/react outline * add @waku/react hooks docs * add @waku/react providers docs * add more snippet comments + fix code indents
9.8 KiB
title |
---|
Build React DApps Using @waku/react |
The @waku/react package provides components and UI adapters to integrate js-waku
into React applications effortlessly. This guide provides detailed steps for using @waku/react
in your project.
Install the Dependencies
First, set up a project using any production-grade React framework or use an existing React application. For this guide, we will create a boilerplate using Create React App (CRA):
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
npx create-react-app [PROJECT DIRECTORY]
yarn create react-app [PROJECT DIRECTORY]
Next, install the @waku/react
package using your preferred package manager:
npm install @waku/react @waku/sdk
yarn add @waku/react @waku/sdk
Create a Relay Node
Use the useCreateRelayNode()
hook to create a Relay Node:
import { useCreateRelayNode } from "@waku/react";
function App() {
// Create and start a Relay Node
const { node, error, isLoading } = useCreateRelayNode({
options: {
defaultBootstrap: true,
emitSelf: true,
}
});
// "node" is the created Relay Node
// "error" captures any error that occurs during node creation
// "isLoading" indicates whether the node is still being created
// Use these to handle states and render the UI in your application
}
Create a Light Node
Use the useCreateLightNode()
hook to create a Light Node and specify the protocols for remote peers:
import { useCreateLightNode } from "@waku/react";
import { Protocols } from "@waku/interfaces";
function App() {
// Create and start a Light Node and wait for remote peers
const { node, error, isLoading } = useCreateLightNode({
options: { defaultBootstrap: true },
protocols: [Protocols.LightPush, Protocols.Filter],
});
// "node" is the created Light Node
// "error" captures any error that occurs during node creation
// "isLoading" indicates whether the node is still being created
// Use these to handle states and render the UI in your application
}
Create an Encoder and Decoder
Use the useCreateContentPair()
hook to create a message encoder
and decoder
pair:
import { useCreateContentPair } from "@waku/react";
function App() {
// Choose a content topic
const contentTopic = "/waku-react-guide/1/message/utf8";
const ephemeral = false;
// Create a message encoder and decoder pair
const { encoder, decoder } = useCreateContentPair(contentTopic, ephemeral);
// "encoder" is the message encoder
// "decoder" is the message decoder
// Use these to handle the messages in your application
}
Send Messages Using Light Push
Use the useLightPush()
hook to bind Light Push
methods to a node and encoder
:
import {
useCreateLightNode,
useCreateContentPair,
useLightPush,
} from "@waku/react";
import { Protocols } from "@waku/interfaces";
import { utf8ToBytes } from "@waku/sdk";
function App() {
// Create and start a Light Node and wait for remote peers
const { node, error, isLoading } = useCreateLightNode({
options: { defaultBootstrap: true },
protocols: [Protocols.LightPush, Protocols.Filter],
});
// Choose a content topic and create an encoder
const contentTopic = "/waku-react-guide/1/message/utf8";
const { encoder } = useCreateContentPair(contentTopic);
// Wait for the node to finish loading before sending messages
// (isLoading === false)
// Bind push method to a node and encoder
const { push } = useLightPush({ node, encoder });
// Send the message using Light Push
const sendMessage = async (text) => {
if (!push || !text) {
return;
}
const payload = utf8ToBytes(text);
await push({ payload });
};
sendMessage("Hello, World!");
}
:::info
Wait for the node to finish loading before sending messages (isLoading
=== false
).
:::
Receive Messages Using Filter
Use the useFilterMessages()
hook to receive messages from a Filter
subscription:
import {
useCreateLightNode,
useCreateContentPair,
useFilterMessages,
} from "@waku/react";
import { Protocols } from "@waku/interfaces";
function App() {
// Create and start a Light Node and wait for remote peers
const { node } = useCreateLightNode({
options: { defaultBootstrap: true },
protocols: [Protocols.LightPush, Protocols.Filter],
});
// Choose a content topic and create a decoder
const contentTopic = "/waku-react-guide/1/message/utf8";
const { decoder } = useCreateContentPair(contentTopic);
// Receive messages from Filter subscription
const { error, messages, isLoading } = useFilterMessages({ node, decoder });
console.log(messages);
// "error" captures any error that occurs while receiving messages
// "messages" contains a list of messages the subscription received
// "isLoading" indicates whether the node is still subscribing to Filter
// Use these to handle states and render the UI in your application
}
Retrieve Messages Using Store
Use the useStoreMessages()
hook to retrieve messages from the Store
protocol:
import {
useCreateLightNode,
useCreateContentPair,
useStoreMessages,
} from "@waku/react";
import { Protocols, PageDirection } from "@waku/interfaces";
function App() {
// Create and start a Light Node and wait for remote peers
const { node } = useCreateLightNode({
options: { defaultBootstrap: true },
protocols: [Protocols.LightPush, Protocols.Filter],
});
// Choose a content topic and create a decoder
const contentTopic = "/waku-react-guide/1/message/utf8";
const { decoder } = useCreateContentPair(contentTopic);
// Set the query options
const options = {
pageDirection: PageDirection.BACKWARD,
pageSize: 20,
};
// Query the Store peer
const { error, messages, isLoading } = useStoreMessages({ node, decoder, options });
console.log(messages);
// "error" captures any error that occurs during message retrieval
// "messages" contains a list of messages retrieved from the Store peer
// "isLoading" indicates whether the node is still retrieving messages
// Use these to handle states and render the UI in your application
}
:::info To explore the available query options, please refer to the Store Query Options guide. :::
Using @waku/react Providers
The @waku/react
package provides a collection of context providers to pass configuration options throughout the component hierarchy:
RelayNodeProvider
The RelayNodeProvider
context provider passes configuration options for creating a Relay Node:
import { RelayNodeProvider } from "@waku/react";
import { Protocols } from "@waku/interfaces";
// Set the Relay Node options
const NODE_OPTIONS = {
defaultBootstrap: true,
emitSelf: true,
};
// Set the remote peer connections to wait for
const PROTOCOLS = [Protocols.Relay];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// Use the Relay Node context provider
<RelayNodeProvider options={NODE_OPTIONS} protocols={PROTOCOLS}>
<App />
</RelayNodeProvider>
</React.StrictMode>
);
import { useWaku } from "@waku/react";
function App() {
// Create and start a Relay Node
const { node, error, isLoading } = useWaku();
// Use these to handle states and render the UI in your application
}
LightNodeProvider
The LightNodeProvider
context provider passes configuration options for creating a Light Node:
import { LightNodeProvider } from "@waku/react";
import { Protocols } from "@waku/interfaces";
// Set the Light Node options
const NODE_OPTIONS = { defaultBootstrap: true };
// Set the remote peer connections to wait for
const PROTOCOLS = [
Protocols.LightPush,
Protocols.Filter,
];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// Use the Light Node context provider
<LightNodeProvider options={NODE_OPTIONS} protocols={PROTOCOLS}>
<App />
</LightNodeProvider>
</React.StrictMode>
);
import { useWaku } from "@waku/react";
function App() {
// Create and start a Light Node
const { node, error, isLoading } = useWaku();
// Use these to handle states and render the UI in your application
}
ContentPairProvider
The ContentPairProvider
context provider passes configuration options for creating an encoder
and decoder
pair:
import { ContentPairProvider } from "@waku/react";
// Choose a content topic
const CONTENT_TOPIC = "/waku-react-guide/1/message/utf8";
const EPHEMERAL = false;
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// Use the content pair context provider
<ContentPairProvider contentTopic={CONTENT_TOPIC} ephemeral={EPHEMERAL}>
<App />
</ContentPairProvider>
</React.StrictMode>
);
import { useContentPair } from "@waku/react";
function App() {
// Create a message encoder and decoder pair
const { encoder, decoder } = useContentPair();
// Use these to handle the messages in your application
}
:::tip
You have successfully integrated js-waku
into a React application using the @waku/react
package. Check out the web-chat example for a working demo.
:::