In this lesson I walk through each file in the application to demonstrate how it's all setup.
This app uses create-react-app and there is organized in a fairly common way.
We have a
components/ folders for our React components and all of the redux logic including
reducers live inside of a
Each component in our application has one or both of mapStateToProps and mapToDispatchToProps as well as both a react class component and redux connected component which we call a "container" component.
Note: This lesson is definitely optional if you're already confident in how a redux app is setup.
Jamund Ferguson: [0:00] This app is set up using create-react-app and it falls a pretty standard setup. There's an index.js file. This file references pretty much only one component, the ExchangeRateContainer, which is found in components/ExchangeRate. That ExchangeRateContainer is wrapped in the Redux Provider, which allows the ExchangeRateContainer and all of its children to access the Redux store.
[0:21] Inside of the components folder you can see I have the ExchangeRate.js file. In its render function you can see the three main parts of our application represented. There's CurrencyCodePicker, AmountField, and RateTable. The name at the bottom of the screen is found inside of the RateTable.
[0:36] Each of the files have prop types and almost all the files in our application use Redux and so, you'll have the familiar mapStateToProps and mapDispatchToProps, as well as the connected version of the component.
[0:50] Each of our components has a class component and then a connected component, which we're calling container.
[0:57] Some of the other components are AmountField, which is fairly straightforward, it pretty much only has an onChange handler. There's also the important debounce that I mentioned. There is the CurrencyCodePicker, and then, finally, the RateTable which simply loops over all the rates and applies a little bit of math to determine what the currency calculation should be before rendering it to the screen.
[1:20] At the bottom, we've got our bounce() function, which is mapped to the onMouseEnter event and it's powered by this bounce class, which we import from "bounce.js".
[1:29] The rest of the interesting stuff in this application lives in the store folder. Here we have our main Redux store. In our store file we have two reducers that are combined together, the rates reducer and our user reducer. For the most part we don't use the user reducer. It simply provides the name that's found at the bottom of the screen. If I change it in here, it will be updated automatically.
[1:50] Our RateReducer is where most of the action happens. Here we set the supportedCurrencies, which are provided in our dropdown and in our RateTable. We also set the default rate, 1. for USD, the default currencyCode, which now is set to EUR, but could be set to JPY or anything else, and our default amount, which currently is 12.99. For any of these, if we change them here, you can see them instantly updated in our application.
[2:20] The reducer itself handles a number of events. There is AMOUNT_CHANGED, CURRENCY_CODE_UPDATED and RATES_UPDATED, which correspond to the various pieces of state in our application. We also have a number of selectors to make it easier to access that state, which are used throughout.
[2:36] A few other files to note are found in the actions folder. There are the ActionTypes constants, AMOUNT_CHANGED, RATES_UPDATED and CURRENCY_CODE_UPDATED, which we reference elsewhere, and our RateActions. These are action creators that are used to update the currency code, to update the rates and the value of the amount field.
[2:53] Lastly, we have a file call api.js, which has a single function called getExchangeRates(). This calls the exchangeratesapi to get the exchange rate information.
[3:03] With that, we pretty much covered all the pieces of our application. Please follow along as we convert this from a legacy Redux app to a modern one, using hooks.