In this session, we will create a new React app and connect it to a Winglang backend.
First, let's verify that you can create a React application using create-react-app
. Make sure you are at the project root directory (not inside backend
).
npx create-react-app client
cd client
npm i --save @babel/plugin-proposal-private-property-in-object
npm start
The result should be a running React website. Once you verify it is working, you can close the server with Ctrl-C
.
- Replace
backend/main.w
with the following content:
bring ex;
bring cloud;
bring http;
let react = new ex.ReactApp(
projectPath: "../client",
);
- Terminate (
Ctrl-C
) your existingwing run
command and rerun it with theBROWSER=none
environment variable:BROWSER=none wing run backend/main.w
BROWSER=none
prevents React from starting a new browser window on every run.
As you can see, you now have a running React web app from within the Wing toolchain.
Wing creates client/public/wing.js
to pass configuration from the Wing backend to the frontend code.
If you examine its content, it is currently:
// This file is generated by Wing
window.wingEnv = {};
Once we add the following code to backend/main.w
:
react.addEnvironment("key1", "value1");
The running wing run
command will generate a new version of client/public/wing.js
:
// This file is generated by wing
window.wingEnv = {
"key1": "value1"
};
Let's see how we can use this mechanism:
- Include
wing.js
in your frontend code - Add the following line insideclient/public/index.html
(just before the<title>
section):<script src="./wing.js"></script>
- Let's see this in action. In
client/src/App.js
, look for "Learn React" (probably around line 18) and replace it with:{window.wingEnv.title || "Learn React"}
- Go to
backend/main.w
and add:react.addEnvironment("title", "Learn React with Wing");
Once we know how to pass parameters from the backend to the client, let's use this capability to set window.wingEnv.apiUrl
on the client and fetch the title from our API.
- Enable cross-origin resource sharing (CORS) by adding
cors: true
andcorsOptions: ...
inbackend/main.w
:
let api = new cloud.Api(
cors: true
);
- To set
apiUrl
, go tobackend/main.w
and add:
react.addEnvironment("apiUrl", api.url);
- Create a new
/title
route inbackend/main.w
:
api.get("/title", inflight () => {
return {
status: 200,
body: "Hello from the API"
};
});
- Use React hooks to read the title from our API. Replace the content of
client/src/App.js
with the following code:
import logo from './logo.svg';
import { useEffect, useState } from "react";
import './App.css';
function App() {
const [title, setTitle] = useState("Default Value");
const getTitle = async () => {
const response = await fetch(`${window.wingEnv.apiUrl}/title`);
setTitle(await response.text());
}
useEffect(() => {
getTitle();
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
{title}
</header>
</div>
);
}
export default App;