Welcome to Part 10 of this comprehensive review and summary of Cory House’s Pluralsight course Building Applications with React and Redux in ES6.
Cory is a Microsoft MVP in C#, founder of OutlierDeveloper.com, avid tech reader, and speaker.
He believes in clean code, pragmatic development, and responsive native UIs.
Also in this series:
Part 1 – Introduction and Background
Part 3 – React Component Approaches
Part 4 – Initial App Structure
Part 6 – Actions, Stores and Reducers
Part 7 – Connecting React to Redux
Async Writes in Redux
Create Manage Course Page
The component that we’re building in this module will be quite complex.
Cory starts by creating the basic structure of our new container. He uses Webstorm’s File Template feature to create a React Redux Container Component.
This is a very useful productivity tip, because this creates a whole load of boilerplate code, which would take at least a couple of minutes to type correctly (probably more), in just a second! What is especially nice is it uses placeholders to use the correct class name based on the file name that we type.
Cory shows us exactly how he set this up. He uses $NAME to map the class name to the file name.
Next, we add two new routes using the ManageCoursePage component, one to the path course, and another to the path course/:id
Both of these are added in routes.js
We see that although there’s not much to see, the manage course page is loading successfully. Now let’s create the form…
Create Manage Course Form
CourseForm.js is a stateless functional component which calls some child components.
Most of the code is JSX, creating a TextInput, a SelectInput, a couple of other TextInput fields and a submit button.
Create Form Input Components
Time to create some reusable components. We create TextInput.js and SelectInput.js and the code isn’t explained here because it was discussed in Cory House’s previous course Building Applications with React and Flux.
Specifically, the clip of interest from his previous course is React Forms – Creating Reusable Inputs.
Use Manage Course Form
In our new ManageCoursePage.js we add a reference to CourseForm and update our render function.
We see that we can only have one top level element in our JSX.
Next, we update mapStateToProps, returning a course object. Then we update our render function again, adding properties for errors and allAuthors.
Whn we run up our Manage Courses screen, see 4 warnings in our console, but the biggest problem that we have at the moment is the author dropdown which is not showing any authors to choose from.
Create Author Actions
Cory says this issue with our authors dropdown is an opportunity to learn more about thunks, actions and reducers.
We start by creating authorActions.js, which is very similar to courseActions.js
We add a new constant LOAD_AUTHORS_SUCCESS which we reference in authorActions.js
Create Author Reducer
We start by creating authorReducer.js, and as you might expect this is very similar to courseReducer.js
Next we create initialState.js in our reducers folder, and this exports arrays for our authors and courses.
Cory explains that as you create more and more reducers, it becomes harder to remember what is in the store. This refactoring makes this information explicit, and gives us a picture of the store in its entirety.
Map Author Data for Dropdown
We update our ManageCoursePage.js to map the author data into the dropdown.
Here we see a couple of properties are missing prop validation. This is caused by a typo, but once fixed we see the authors Cory House, Scott Allen and Dan Wahlin appearing in our dropdown and available for selection.
Cory reminds us that Redux is valuable for complex apps. For trivial apps like the one we’re building here the boilerplate feels tedious, but it pays off increasingly as the app grows larger.
Create Form Change Handler
The next issue is we can’t type into the textbox fields!
In our ManageCoursePage.js, first we add an updateStateCourse function which returns this.setState({course: course});
Then we update our render function with onChange={this.updateStateChange}
We can now type into the fields. Next we need to save our data.
Create Save Course Thunk
In courseActions.js we add a saveCourse thunk function.
This is very similar to the loadCourses thunk that we creates in Part 9 – Async in Redux
Handle Creates and Updates in Reducer
In courseReducer, we add a handler for CREATE_COURSE_SUCCESS, using the spread operator to express this more succinctly.
Next we add a handler for UPDATE_COURSE_SUCCESS.
Dispatch Create and Update
Back to ManageCoursePage.js. we update render with onSave={this.saveCourse} and add actions as a required object in our propTypes validations.
We also update our browserHistory so that the back button will work correctly.
When we run the app, we see that although the save button works, it’s not immediately apparent to the user because we stay on the same screen. So let’s implement a redirect.
Redirect via React Router Context
Underneath our propTypes validation, Cory adds us contextTypes adding router as a required object, and explains that this makes router available to us throughout the manageCourse component.
When we add a new course, we are now redirecting to our course list and can see our new entry at the bottom of the list.
However, when we select a course for edit, it redirects but does not populate the form for us.
Populate Form via mapStateToProps
In ManageCoursePage.js mapStateToProps we add a call to a new function getCourseById.
getCourseById uses filter to match by id and then returns the first matching element.
We see that we also need to add logic so that we only call getCourseById when at least one course has been loaded.
We see that this half works but we have a bug. Cory explains that we need to use a lifecycle method here.
Update State via componentWillReceiveProps
We add componentWillReceiveProps into ManageCoursePage.js
Cory teaches us that this will run sometimes even when props haven’t changed, i.e. when React thinks props might have changed.