Project Summary
This is a working project that currently only utilizes state and props to pass its data. Before getting started, try to get familiar with the code and see how props is being passed through to different components. In particular, take a look at src/App.js
. You’ll notice that src/App.js
is currently very large. With the use of redux
, will be able to turn src/App.js
into a small, 27 line, file.
During this project, I’ll be improving on a web application that walks users through filling out a home loan application. I’ll be modifying components that have already been built to use redux
. This allows us to keep track of data and pass it to the correct components via routing. I’ll be making changes to all files in the src/components
folder, except for src/components/Finish/Finish.js
, to modify them to work with redux
. I’ll also make changes to src/router.js
, src/index.js
and src/App.js
.
Live Example
Setup
fork
andclone
this repository.cd
into the project directory.- Run
npm i
to install current dependencies. - Run
npm i react-redux redux react-router-dom
- Run
npm start
( The app should intentionally not compile correctly ).
Step 1
Summary
In this step, we will create our store
. When using redux, the store holds the entire state of our application. So it’s important we set this up first.
Instructions
- Create a new file in your
src
folder calledstore.js
- Open
src/store.js
. - Import
createStore
fromredux
. - Import
reducer.js
fromsrc/ducks/reducer.js
. - Export
createStore
by default and pass it reducer as it’s argument
Detailed Instructions
Solution
src/store.js
Step 2
Summary
In this step, we will take our store created from the previous step and hook it up in src/index.js
. We will also make use of HashRouter
in App.js
to allow routing in the application. After this step, our app should compile correctly.
Instructions
- Open
src/index.js
. - Import
store
fromsrc/store.js
. - Import
Provider
fromreact-redux
. - The
Provider
component should have astore
prop that equalsstore
(remember how we reference variables in jsx). - Open
src/App.js
. - Import
HashRouter
fromreact-router-dom
. - Wrap the
router
invocation in<HashRouter>
tags.
Detailed Instructions
Solution
src/index.js
src/App.js
Step 3
Summary
Because we needed to pass state down to our routes, we had to make our routing a function. Currently, we’re exporting a function by default in our router.js
, by making this a function, we were able to import it into our App.js
and then pass it props through its arguments.
In addition to our route component being a function, the way we’re connecting our Route
to the correct component is using a render={()=> <Component prop={prop}/> path='/'}
instead of a component={Component} path='/'
. The reason we needed to use render this way was so we could pass props down through the Components element. However, this results in messy looking code.
In this step, we are going to clean up the mess.
Instructions
- Open
src/router.js
. - Instead of exporting a function, let’s remove the function and simply export the chunk of JSX that was returned by the function.
- You will start getting errors coming from the props on the routes rendered elements once our routing is no longer a function, this is because they’re no longer receiving information via parameters from the function and are now undefined.
- For each individual route, instead of using render, we will be using component.
- A route should look like the following:
<Route component={ theComponent } path='/thePath'/>
Now that we’ve changed our router.js
, no data is going to be passed to our other components, you will also get an error that says TypeError: __webpack_require__.i(...) is not a function
. This is because in our App.js
router is still being treated as a function.
- Open
src/App.js
. - Remove the invoking parenthesis from your
{router}
as well as the content inside of them.
Detailed Instructions
Solution
src/router.js
src/App.js
Step 4
Summary
In this step, I’ll be removing the state and handler methods from App.js
. That’s because we no longer need either. Instead, all of our wizard steps (components) will connect to the redux store separately, and we don’t need to track state in App.js
, just for the sake of passing it down as props.
Instructions
- Open
src/App.js
. - In the App component, delete the constructor and state.
- Delete all the handler methods.
- In the return statement of
render()
, delete everything but thediv
with the router.
Solution
src/App.js
Step 5
Summary
Let’s begin connecting our views. I’ll start with the Eleventh view. I chose the Eleventh view because as we start hooking our views up with redux
, I’ll be able to see the data getting to where it needs to end up.
Instructions
- Open
src/components/WizardEleven/WizardEleven.js
. - Import
connect
fromreact-redux
- Connect the component to the
redux store
. - Instead of
returning
the entire state inmapStateToProps
, return only the properties the component needs: Properties
- You may be scratching your head as to why we are using these exact propeties. When we setup the reducer later on, these will be the names of the properties the
redux
store will be managing.
Detailed Instructions
Solution
src/components/WizardEleven/WizardEleven.js
Step 6
Summary
Now let’s take a look at our first view: src/components/WizardOne/WizardOne.js
. It looks like we need to be able to update the loanType
and propertyType
items on state. In redux, in order to update something, we need to have a reducer and action creators.
In this step, I’ll start creating our store’s reducer and the action creators to update loanType
and propertyType
.
Instructions
- Open
src/ducks/reducer.js
. - Create an
initialState
object, at the very top of the file, with the following properties: Initial State Properties
- Modify the
reducer
function to have a state and action parameter. - The
state
parameter should default toinitialState
. - Create two action types in between
initialState
and thereducer
function. - The first action type should equal:
"UPDATE_LOAN_TYPE"
. - The second action type should equal:
"UPDATE_PROPERTY_TYPE"
. - Create two action creators in between the
reducer
function and theexport default
statement. - The first action creator should have a type of
UPDATE_LOAN_TYPE
. - This action creator should have a parameter called
loanType
. - This action creator should have a payload that equals
loanType
. - The second action creator should have a type of
UPDATE_PROPERTY_TYPE
. - This action creator should have a parameter called
property
. - This action creator should have a payload that equals
property
. - Modify the
reducer
function to use aswitch
statement on theaction.type
. - Create a
case
forUPDATE_LOAN_TYPE
and update state with the new loan type. - Create a
case
forUPDATE_PROPERTY_TYPE
and update state with the new property type. - Create a
default case
that returns state.
Detailed Instructions
Solution
src/ducks/reducer.js
Step 7
Summary
In this step, we will connect src/components/WizardOne/WizardOne.js
to the store and configure the component to use the action creators we have created so far.
Instructions
- Open
src/components/WizardOne/WizardOne.js
. - Import
connect
fromreact-redux
. - Import the
updateLoanType
andupdatePropertyType
action creators fromsrc/ducks/reducer.js
. - Hint: Use destructuring.
- Modify the
export default
statement to useconnect
. - Use
mapStateToProps
to return the only two parts ofstate
it will need. - Use a second parameter on the
connect
statement that passes in the action creators. - Modify the two
onChange
events to use the action creators. - Hint: Both action creators need an argument.
Detailed Instructions
Solution
src/components/WizardOne/WizardOne.js
Step 8
Summary
In this step, we will update the reducer to handle modifying the city on state. We will also configure the src/components/WizardTwo/WizardTwo.js
to connect to the store and use an action creator to update the city on state.
Instructions
- Open
src/ducks/reducer.js
. - Create an action type for
UPDATE_CITY
. - Create an action creator called
updateCity
. - This action creator should use a parameter called
city
. - Add an
UPDATE_CITY
case to the reducer that updatescity
. - Remember to keep state immutable.
- Open
src/components/WizardTwo/WizardTwo.js
. - Import
connect
fromreact-redux
. - Import
updateCity
fromsrc/ducks/reducer.js
. - Modify the
export default
statement to use connect. mapStateToProps
should only return one property from state.updateCity
should be passed in as a second parameter.- Modify the
onChange
event to callupdateCity
. - Remember this action creator has one parameter.
Detailed Instructions
Solution
src/ducks/reducer.js
src/components/WizardTwo/WizardTwo.js
Step 9
Summary
In this step, we will update the reducer to handle modifying the propToBeUsedOn
on state. We will also configure src/components/WizardThree/WizardThree.js
to connect to the store and use an action creator to update propToBeUsedOn
on state.
Instructions
- Open
src/ducks/reducer.js
. - Create an action type for
UPDATE_PROP
. - Create an action creator called
updateProp
. - This action creator should use a parameter called
prop
. - Add an
UPDATE_PROP
case to the reducer that updatespropToBeUsedOn
. - Remember to keep state immutable.
- Open
src/components/WizardThree/WizardThree.js
. - Import
connect
fromreact-redux
. - Import
updateProp
fromsrc/ducks/reducer.js
. - Modify the
export default
statement to use connect. mapStateToProps
should only return one property from state.updateProp
should be passed in as a second parameter.- Modify the
onClick
events to callupdateProp
. - Remember this action creator has one parameter.
Detailed Instructions
Solution
src/ducks/reducer.js
src/components/WizardThree/WizardThree.js
Step 10
Summary
In this step, we will update the reducer to handle modifying the found
on state. We will also configure src/components/WizardFour/WizardFour.js
to connect to the store and use an action creator to update found
on state.
Instructions
- Open
src/ducks/reducer.js
. - Create an action type for
UPDATE_FOUND
. - Create an action creator called
updateFound
. - This action creator should use a parameter called
found
. - Add an
UPDATE_FOUND
case to the reducer that updatesfound
. - Remember to keep state immutable.
- Open
src/components/WizardFour/WizardFour.js
. - Import
connect
fromreact-redux
. - Import
updateFound
fromsrc/ducks/reducer.js
. - Modify the
export default
statement to use connect. mapStateToProps
should only return one property from state.updateFound
should be passed in as a second parameter.- Modify the
onClick
events to callupdateFound
. - Remember this action creator has one parameter.
Detailed Instructions
Solution
src/ducks/reducer.js
src/components/WizardFour/WizardFour.js
Step 11 – Challenge
Summary
In this step, we will complete the rest of the reducer for updating the remaining properties on state. We want this step to be a challenge for you, meaning there will not be any guided instructions. Try to complete this step without looking at any previous steps. If you get stuck, try looking back at the previous three steps.
Instructions
- Open
src/ducks/reducer.js
. - Create an action type for updating the following state properties:
realEstateAgent
cost
downPayment
credit
history
addressOne
addressTwo
addressThree
firstName
lastName
email
- Create an action creator for each property listed above.
- Update the reducer to have a case for each new action type.
- The case should update state with the value on the payload.
- Remember to keep state immutable.
Solution
src/ducks/reducer.js
Step 12 – Challenge
Summary
In this step, we will hook up the rest of the views to the store and modify the events to call our action creators. We want this step to be a challenge for you, meaning there will not be any guided instructions. Try to complete this step without looking at any previous steps. If you get stuck, try looking back steps eight through ten.
Instructions
Open the remaining wizard
components ( Wizard 5-10 ) and update them to connect to the store. Remember to use mapStateToProps
to grab only the property(s) that component is modifying. Also remember to pull in the action creator(s) from the reducer. Then modify the events in the component ( onChange
|| onClick
) to call the action creator(s).
Solution
src/components/WizardFive/WizardFive.js
src/components/WizardSix/WizardSix.js
src/components/WizardSeven/WizardSeven.js
src/components/WizardEight/WizardEight.js
src/components/WizardNine/WizardNine.js
src/components/WizardTen/WizardTen.js
Contributions
If you see a problem or a typo, please fork, make the necessary changes, and create a pull request so we can review your changes and merge them into the master repo and branch.
Copyright
© RomanFSDev LLC, 2017. Unauthorized use and/or duplication of this material without express and written permission from RomanFSDev, LLC is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to RomanFSDev with appropriate and specific direction to the original content