With the reducer finished for now at least regarding ingredients,
let's connect the burger builder container to our store.
We already set up the store here in the index.js file, pass it to provider and wrapped everything
with provider,
so now it's time to work on the burger builder to receive that data there.
And you learned how that works,
it works with the connect function
we import from react-redux.
So let's import connect from there, from react-redux like this and with that import added, let's wrap
our export with it.
Now to be precise, let's not wrap it with it, let's simply wrap the mapDispatchToProps and mapStateToProps
constants with it and pass the burger builder to it.
But here we face an issue, we already have a higher order component wrapping our export, the withErrorHandler
high order component we set up here.
Well this actually isn't a problem,
you can have as many higher order components in there as you want.
In the end what connect will do is it will just set some props on the component it's wrapping,
so as long as you pass this props on in your own higher order components, this should work fine because
any props set by other higher order components which might wrap this one will still be passed on just
fine,
so this shouldn't pose an issue at all,
so let's see if this works. Let's go back to burger builder and let's create our two constants which define
which props we get into burger builder, mapDispatchToProps and mapStateToProps, I'll reverse the order
because I did so before, so const mapStateToProps. Now mapStateToProps holds a function which
receives the state automatically and which returns a javascript object where we define which property
should hold which slice of the state.
So here, we could create ings for ingredients and assign state.ingredients just like that, to get access
to that ingredients property in our state and dispatch to props now receives a function or holds a
function which receives the dispatch function as an argument
and then also the returns object with props function mappings
in this case and here I want to have two dispatchable props basically or two props which can be
triggered,
I'll have a onIngredientAdded property and this property name, as this one here of course is totally
up to you.
So here onIngredientAdded will hold an anonymous function where I then execute dispatch and pass a javascript
object where the type should now be my ADD_INGREDIENT action type and for that, I'll move all the way up
to the file and import everything as action types from this action types folder which we can find two
levels up in the store folder in the actions.js file,
this is where the action types are stored.
So now, this is what I'll sign here,
type is actionTypes.ADD_INGREDIENT.
And now if we have a look at the reducer and probably you also remember, add ingredient, just like remove
ingredient requires a payload.
We use the ingredient name there and we access it on the action
so we need to pass the ingredient name along with the type.
So back in the burger builder here, the type is one thing but I'll also set up my ingredient name action
property and ingredient name
now is something I expect to get here in this function so I'll simply name it ingName here,
you can name this argument whatever you want of course and then I'll assign it here as a value. I'll then
duplicate this property and add my on ingredient removed property where it also needs the ingredient
name
but then here, I dispatch the remove ingredient action but still pass my ingredient name on.
Now with these two constants, mapStateToProps and mapDispatchToProps set up, we can connect
our component to redux.
So let's add connect, we already imported it and let's pass mapStateToProps and mapDispatchToProps
as arguments and then let's pass this entire withErrorHandler call here as an argument to the
function, this connect function call returns us. With this set up
now, we have our burger builder container connected to the store,
let's now use all these props we make available in the burger burger, like ings. Everywhere, where
we use ingredients, we now want to use ings
and I will remove ingredients from here to make it really clear that we're not using the local state
for ingredients anymore for the price we will, right now at least.
So let's fix this or let's set this up, add ingredient and remove ingredient handler,
we should be able to entirely remove that
but I will leave it here since we later picked a total price updated code from there
but we don't want to execute them anymore.
Instead if we scroll down to the render method, wherever we access this.state.ingredients, we want to
use this.props.ings instead,
this property we set up in mapStateToProps
here. So this is what we want to use in our render method, this.props.ings instead of state
ingredients. State error and so on
will stay untouched for now
but here for example, state ingredients this is state, this.props.ings
and then here our burger where we pass the ingredients,
guess what,
it's this.props.ings
and so on.
Now I will first of all replace all ingredients before I work on the ingredient added and remove props here
so let me go on, here
also this is this.props.ings and that should be it.
Now let's work on the add ingredient and remove ingredient handlers,
we don't call that anymore
instead we execute this.props on ingredient added and this.props on ingredient removed but both functions
at the end need an argument.
If we scroll down to our mapDispatchToProps constant, we see that the functions stored in these
props or passed onto these props,
both take the ingredient name as an argument. To pass this on here,
let's first of all have a look at our build controls component,
if we scroll to our components and we open the build controls folder and go into the build controls component,
we see that we already pass control type here as an argument to the ingredient added and removed props
methods,
so to the method which gets passed through these props and that happens to be the method we just set
up here.
Now that just means we have to check if control type is exactly what we're looking for and it is because
control type is this part here type salad, bacon, cheese and meat
an that has the same format as the names we use as properties in our reducer code and of course, we
should make sure that this is equal.
You could of course go so far and refactor your application to take the ingredient state, the property
names here to create your controls in the burger builder, in the build controls
component here. But we'll leave it as it is and we're just making sure that we're passing the correct value
to our action dispatchers and we do. So save all the files then
and now let's try this out.
Back in our running application, let's add some ingredients to that burger, like salad, bacon, cheese
or meat and this is all working fine.
Now obviously, the price is not updating here because what we have here is that we don't change the price
state at any point of time anymore but
we'll take care about this soon.
The rest is working though,
well the order now button also isn't becoming active.
Let's have a look at that order now button then,
the reason why it's not becoming active is that in the end, it's controlled through this purchasable property
here,
we had a look at this earlier in this module. So the order now button price,
these are two things we'll have to work on, the ingredients on their own though are already working great
in the burger builder.
Let's continue this road and let's also make sure that the order now button works and that we update
the price.