React
- Make sure your Reboot application is running
- Python
- TypeScript
source ./.venv/bin/activate
rbt dev runnpx rbt dev run
- Setup your frontend folder
mkdir web && cd web
- Create Vite project
npm create vite@latest . -- --template react-ts
- Install
@reboot-dev/reboot-react
npm install @reboot-dev/reboot-react
- Add
RebootClientProvider
tosrc/main.tsx
// ./src/main.tsx
import { RebootClientProvider } from "@reboot-dev/reboot-react";
// ...
// Matching the URL that `rbt dev run` prints out.
const url = "http://localhost:9991";
// ...
<RebootClientProvider url={url}>
<App />
</RebootClientProvider>
// ... - Generate React API files
Add the following line to your existing
.rbtrc
file:generate --react=web/src/api
In the terminal running
rbt dev run
you'll see that the change is detected and the React code is generated. - Replace exiting code in
src/App.tsx
// ./src/App.tsx
import { useState } from "react";
import { useHello } from "./api/hello/v1/hello_rbt_react";
// TODO: import "./App.css";
const App = () => {
const [message, setMessage] = useState("Hello, Reboot!");
const { useMessages, send } = useHello({ id: "reboot-hello" });
const { response } = useMessages();
const handleSend = async () => {
if (message.trim()) {
await send({ message });
setMessage("");
}
};
return (
<div className="app-container">
<h3 className="app-title">This is Reboot 🎉</h3>
<div className="messages-container">
{response?.messages.map((msg, index) => (
<div key={index} className="message">{msg}</div>
))}
{/* TODO: render pending messages optimistically. */}
</div>
<div className="input-container">
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSend()}
placeholder="Type your message here..."
className="message-input"
/>
<button onClick={handleSend} className="send-button">
Send
</button>
</div>
</div>
);
};
export default App; - Add styling (optional)
/* ./src/App.css */
.app-container {
max-width: 500px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
font-family: Arial, sans-serif;
}
.app-title {
text-align: center;
font-weight: normal;
margin-bottom: 20px;
}
.messages-container {
margin-bottom: 20px;
max-height: 300px;
overflow-y: auto;
}
.message {
background-color: #e3f2fd;
padding: 8px 12px;
margin: 4px 0;
border-radius: 12px;
word-wrap: break-word;
color: black;
}
.pending-message {
background-color: #fff3cd;
padding: 8px 12px;
margin: 4px 0;
border-radius: 12px;
word-wrap: break-word;
opacity: 0.8;
}
.input-container {
display: flex;
gap: 8px;
}
.message-input {
padding: 10px;
flex: 1;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
}
.message-input:focus {
border-color: #007bff;
}
.send-button {
padding: 10px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
}
.send-button:hover {
background-color: #0056b3;
}Then replace this line in your
App
component:// TODO: import "./App.css";
With:
import "./App.css";
- Start your React app
npm run dev
- Test your app
View your app at
http://localhost:3000
🎉. Try opening your app in multiple browser tabs! - Add optimistic updates (optional)
Replace this line in your
App
component:{/* TODO: render pending messages optimistically. */}
With this code:
{send.pending.map(({ request: { message } }, index) => (
<div key={`pending-${index}`} className="pending-message">
{message} (sending...)
</div>
))}This will show messages immediately when you click Send, even before the backend confirms they've been processed. Try it out by making your backend sleep for a few seconds in the
send
method!
Next steps​
Well done! You made it! Check out these links to continue your exploration:
- Learn advanced React usage - like error handling, or Next.js and Server Components.
- Learn about transactions - so far,
we've covered
reader
andwriter
methods, but Reboot's power extends totransactions
. Learn abouttransactions
and all of the other method kinds here. - Join us on Discord - to ask questions and let us know what you think!