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 install
to install the required dependencies.In src/index.js, create React components called
Home
andEditor
.Add a constructor to the App react component. In the constructor:
Take in the
props
variable. Callsuper
and passprops
intosuper
.Set the
state
object in thethis
scope. It must have a property calledview
with the valuehome
.Add a
changeView
method to the app.The
changeView
method should take in a parameter calledview
.Update the state with
setState
and set theview
property of thestate
equal to the provided parameterview
.In the constructor, add a line that sets
this.changeView
equal tothis.changeView.bind(this)
.In App’s
render
function, create a conditional rendering based on the value ofthis.state.view
that does the following:If
state.view
is equal tohome
, show the home view. Otherwise, show the editor view.Pass the
changeView
function as a parameter to both views, which are<Editor
changeView={this.changeView}/>
and<Home changeView={this.changeView}/>
.In the
Home
component, add agoEdit()
function, whichcalls
thechangeView
function passed in throughprops
(this.props.changeView
). and passes in the stringeditor
to thechangeView
function.Create the
render
function in theHome
component:Return a JSX expression.
To the returned JSX expression, add a
div
that contains a title headingtitle
of the appNote Editor App
, and add a button that changes the view to theEdit
view.The button should call the
goEdit
function on click. Be sure to properly bind thethis
state to thegoEdit
function.Add a constructor to the
Editor
component:Take in the
props
parameterCall
super
and pass in theprops
variable.Set the
state
variable in thethis
scope equal to the{value: ‘’}
object.Add a function called
handleChage
toEditor
:Takes in an argument,
e
, that represents the event object.Update the state with
setState
to set the state propertyvalue
equal to the event target’s value:this.setState( { value: e.target.value } );
Create a
save
function inEditor
that makes an HTTP request to the API save route.Create a new XHR request and save it into the
xhttp
variable.Set the
xhttp
propertyonreadystatechange
to a function that checks if this.readyState
is equal to4
. If it is not, then return. Also, check ifthis.status
is equal to200
. If it is not, then throw an error.Open the
xhr
request by calling theopen
function onxhttp
. Pass in the parametersPOST
,/save
, andtrue
.Set the request header
Content-Type
toapplication/json;charset=UTF-8
by calling thesetRequestHeader
on thexhttp
object. 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
load
function inEditor
that makes an HTTP request to the API load route.Create a new XHR request and save it into the
xhttp
variable.Save the
this
scope into a variable calledthat
so that it can be used inside thexhr
request.Set the
xhttp
propertyonreadystatechange
to a function that checks ifthis.readyState
is equal to4
. If it isn’t, then return. It then checks ifthis.status
is equal to200
. If it is not, then throw an error. It calls thesetState
function on the React component’s scope, which is saved in thethat
variable.Pass in an object with the key
value
equal to the parsed response of the request. Parse the HTTP response value from thethis.response
variable with theJSON.parse
function.Open the HTTP request by calling the
open
function on thexhttp
variable. Pass in the parametersGET
,/load
, andtrue
.Send the XHR request by calling the
send()
method on thexhttp
object.Create a
goHome
function inEditor
.Call the
changeView
function that was passed in through the React element properties object (this.props.changeView()
).Pass in the string
home
.Create the
render
function inEditor
.Add a button that, once clicked, calls the
goHome
function that contains the textBack to home
. It calls thegoHome
function on the click event. Make sure to properly bind thethis
scope to the function.Add a
text
input that contains the note text. The text input loads its value from thestate.value
field. Thetext
field calls thehandleChange
function on a change event. Make sure to properly bind thethis
scope to thehandleChange
function.Add a button to load the note data from the server that contains the text
Load
. It calls theload
function on the click event. Be sure to properly bind thethis
scope to the load function call.Add a button to save the note data to the server that contains the text
Save
. It calls thesave
function on the click event. Be sure to properly bind thethis
scope to the save function call.Be sure to bind the
this
state properly to all listeners.Test the code when ready by doing the following:
Running
npm run build
in the root project folder to transpile the code from JSX.Running
npm start
to 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 home
buttons.Testing the
save
functionality by entering text into thetext
input, saving it, and checking the text file that was created in the folder to see if it matches.Testing the
load
functionality by entering text into the text file, loading it, and making sure that the value in thetext
input 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:
You have successfully built a working React frontend and integrated it with a Node.js express server.