Who doesn't want to look at pictures of cats? Well, now you can look at up to 20 pictures of cats with our new React + Redux app. All you have to do is...build it yourself! Let's get started.
- Use Redux-Thunk middleware to make an asynchronous web request in an action creator function
- Dispatch an action from the
componentDidMount
lifecycle method.
We'll build out our app following the container pattern. We'll have one top-level component, App
, that connects to the store and gets data from the state via mapStateToProps
. App
will render a child presentational component, CatList
, which will recieve the list of cat pics from App
and render them in a series of <img>
tags.
We'll be getting our cat pics from a real API! Sort of. We made a very special API just for you to use with this lab (aren't you so lucky). Clone down this repo, run npm install
and npm start
. If you point your browser to http://localhost:4000/db
you should see a JSON collection of 20 cat image objects.
Our action creator function will be making a request to http://localhost:4000/db
to receive these cat images.
First things first, use Redux's createStore
function to initialize your store in src/index.js
. Define your rootReducer
in reducers/index.js
to use the combineReducers
function with your catsReducer
.
Once you initialize your store with the reducer and middleware, make sure you pass it to the <Provider>
component and wrap your <App>
component in the <Provider>
in src/index.js
.
Define your catsReducer
in src/reducers/cats_reducer
. Your catsReducer
should respond to one action, an action with a type of 'FETCH_CATS'
.
Define your action creator function, fetchCats
in src/actions/catActions
. This action should use fetch
to make the web request for your cat pic JSON. It should use a then
function to parse the JSON of the response to this request, and another .then
function chained on that to grab the actual collection of cat pic image objects. Something like:
fetch('http://localhost:4000/db').then(response => {
return response.json()
}).then(responseJSON => {
return responseJSON.images
})
Save the results of this fetch
request to a const
, cats
, and make sure your action creator function returns an object with a type of 'FETCH_CATS'
and a payload of the cats
collection.
Your App
component should use connect
and mapStateToProps
to set a prop of catPics
to the cats collection in state.
This is something new, so read carefully...
You might be wondering when/where we will actually dispatch our fetchCats
action in order to get all the cat pics into state. We want our cat pics to be fetched when the App
component is first loaded up. So, we'll enact a common pattern in which we hook into a component lifecycle method to fetch the cat pics.
The componentDidMount
function will always be called automatically after render
gets called by our component, when the component is mounting for the first time. This is the perfect place to go and get the cat pics.
We can define our componentDidMount
function like this:
// src/App.js
...
class App extends React.Component {
componentDidMount() {
// fetch the cats
}
render() {
return (...)
}
}
So, we want to dispatch the fetchCats
function from inside our component, specifically from inside the componentDidMount
function. We'll need to use mapDispatchToProps
in order to make our fetchCats
function dispatch-able from within our component.
Once you successfully fetch cats, put them in state, grab them from state and pass them to App
under the catPics
prop, you're ready to build the CatList
component.
Your container component, App
, should render the presentational component, CatList
. App
should pass catPics
down to CatList
as a prop. CatList
should iterate over the cat pics and display each cat pic in an image URL. Remember to use debugger to take a look at the catPics
collection and determine which property of each catPic
object you will use to populate your <img>
tag and render the image.