Chapter 6: JavaScript Ecosystem
Activity 6 – Building a Frontend with React
The frontend team working on your note-taking app from Exercise 35 has unexpectedly quit. You must build the frontend for this application using React. Your frontend should have two views: a Home view and an Edit view. Create a React component for each view. The Home view should have a button that changes the view to the Edit view. The Edit view should have a button that switches back to the Home view, a text input that contains the note text, a load button that calls the API load route, and a save button that calls the API save route. A Node.js server has been provided. Write your React code in activities/activity6/activity/src/index.js. When you are ready to test your code, run the build script (defined in package.json) before starting the server. You can reference the index.html file from Exercise 35 for hints on how to call the API routes.
To build a working React frontend and integrate it with a Node.js express server, follow these steps:
Begin working in "activity/activity6/activity". Run
npm installto install the required dependencies.In src/index.js, create React components called
HomeandEditor.Add a constructor to the App react component. In the constructor:
Take in the
propsvariable. Callsuperand passpropsintosuper.Set the
stateobject in thethisscope. It must have a property calledviewwith the valuehome.Add a
changeViewmethod to the app.The
changeViewmethod should take in a parameter calledview.Update the state with
setStateand set theviewproperty of thestateequal to the provided parameterview.In the constructor, add a line that sets
this.changeViewequal tothis.changeView.bind(this).In App’s
renderfunction, create a conditional rendering based on the value ofthis.state.viewthat does the following:If
state.viewis equal tohome, show the home view. Otherwise, show the editor view.Pass the
changeViewfunction as a parameter to both views, which are<EditorchangeView={this.changeView}/>and<Home changeView={this.changeView}/>.In the
Homecomponent, add agoEdit()function, whichcallsthechangeViewfunction passed in throughprops(this.props.changeView). and passes in the stringeditorto thechangeViewfunction.Create the
renderfunction in theHomecomponent:Return a JSX expression.
To the returned JSX expression, add a
divthat contains a title headingtitleof the appNote Editor App, and add a button that changes the view to theEditview.The button should call the
goEditfunction on click. Be sure to properly bind thethisstate to thegoEditfunction.Add a constructor to the
Editorcomponent:Take in the
propsparameterCall
superand pass in thepropsvariable.Set the
statevariable in thethisscope equal to the{value: ‘’}object.Add a function called
handleChagetoEditor:Takes in an argument,
e, that represents the event object.Update the state with
setStateto set the state propertyvalueequal to the event target’s value:this.setState( { value: e.target.value } );Create a
savefunction inEditorthat makes an HTTP request to the API save route.Create a new XHR request and save it into the
xhttpvariable.Set the
xhttppropertyonreadystatechangeto a function that checks if this.readyStateis equal to4. If it is not, then return. Also, check ifthis.statusis equal to200. If it is not, then throw an error.Open the
xhrrequest by calling theopenfunction onxhttp. Pass in the parametersPOST,/save, andtrue.Set the request header
Content-Typetoapplication/json;charset=UTF-8by calling thesetRequestHeaderon thexhttpobject. Pass in the values specified.Send the JSON data of the text input with
xhttp.send.The value to which, we must send is stored in
this.state. Stringify the value before sending it.Create a
loadfunction inEditorthat makes an HTTP request to the API load route.Create a new XHR request and save it into the
xhttpvariable.Save the
thisscope into a variable calledthatso that it can be used inside thexhrrequest.Set the
xhttppropertyonreadystatechangeto a function that checks ifthis.readyStateis equal to4. If it isn’t, then return. It then checks ifthis.statusis equal to200. If it is not, then throw an error. It calls thesetStatefunction on the React component’s scope, which is saved in thethatvariable.Pass in an object with the key
valueequal to the parsed response of the request. Parse the HTTP response value from thethis.responsevariable with theJSON.parsefunction.Open the HTTP request by calling the
openfunction on thexhttpvariable. Pass in the parametersGET,/load, andtrue.Send the XHR request by calling the
send()method on thexhttpobject.Create a
goHomefunction inEditor.Call the
changeViewfunction that was passed in through the React element properties object (this.props.changeView()).Pass in the string
home.Create the
renderfunction inEditor.Add a button that, once clicked, calls the
goHomefunction that contains the textBack to home. It calls thegoHomefunction on the click event. Make sure to properly bind thethisscope to the function.Add a
textinput that contains the note text. The text input loads its value from thestate.valuefield. Thetextfield calls thehandleChangefunction on a change event. Make sure to properly bind thethisscope to thehandleChangefunction.Add a button to load the note data from the server that contains the text
Load. It calls theloadfunction on the click event. Be sure to properly bind thethisscope to the load function call.Add a button to save the note data to the server that contains the text
Save. It calls thesavefunction on the click event. Be sure to properly bind thethisscope to the save function call.Be sure to bind the
thisstate properly to all listeners.Test the code when ready by doing the following:
Running
npm run buildin the root project folder to transpile the code from JSX.Running
npm startto start the server.Loading the URL specified when the server start (
127.0.0.1:PORT).Testing the view changes by clicking the Edit and
Back to homebuttons.Testing the
savefunctionality by entering text into thetextinput, saving it, and checking the text file that was created in the folder to see if it matches.Testing the
loadfunctionality by entering text into the text file, loading it, and making sure that the value in thetextinput matches the value in text file.
A condensed snippet is provided in the following snippet. Refer to activities/activity6/solution/src/index.js for the full solution code.
Index.js
class Editor extends React.Component {
constructor( props ) { ... }
handleChange( e ) { ... }
save() { ... }
load() { ... }
goHome() { ... }
render() {
return (
<div>
<button type="button" onClick={this.goHome.bind( this )}>Back to home</button>
<input type="text" name="Note Text" value={this.state.value} onChange={this.handleChange.bind( this )}/>
<button type="button" onClick={this.load.bind( this )}>Load</button>
<button type="button" onClick={this.save.bind( this )}>Save</button>
</div>
);
}
}
class Home extends React.Component {
goEdit() { ... }
render() {
return (
<div>
<h1>Note Editor App</h1>
<button type="button" onClick={this.goEdit.bind( this )}>Edit Note</button>
</div>
);
}
}
//{…}Snippet 6.42: React component
Outcome:
Take a look at the output screenshots here:

Figure 6.13 : Edit view

Figure 6.14 : Server view

Figure 6.15 : Running the server to test code
You have successfully built a working React frontend and integrated it with a Node.js express server.