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 startThe result should be a running React website. Once you verify it is working, you can close the server with Ctrl-C.
- Replace
backend/main.wwith the following content:
bring ex;
bring cloud;
bring http;
let react = new ex.ReactApp(
projectPath: "../client",
);- Terminate (
Ctrl-C) your existingwing runcommand and rerun it with theBROWSER=noneenvironment variable:BROWSER=none wing run backend/main.w
BROWSER=noneprevents 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.jsin 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.wand 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: trueandcorsOptions: ...inbackend/main.w:
let api = new cloud.Api(
cors: true
);- To set
apiUrl, go tobackend/main.wand add:
react.addEnvironment("apiUrl", api.url);- Create a new
/titleroute 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.jswith 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;