buyCake: () => dispatch(buyCake())
This will declare buyCake to be a function that takes no arguments, and calls dispatch in its body; but buyCake itself won't be called until you explicitly call it.
It's more or less conceptually equivalent to:
function buyCake() {
dispatch(buyCake());
}
I say conceptually because there are some technical differences between regular functions and arrow functions (a.k.a. lambdas, lambda expressions); see this for more info.
On the other hand
buyCake: dispatch(buyCake())
will set buyCake to the result of the call to dispatch (dispatch will be called immediately, right there).
It's the same as the difference between:
const getSinPI = () => Math.sin(Math.PI); // a function named `getSinPI`
getSinPI(); // returns approx. 0
and
const sinPI = Math.sin(Math.PI); // a variable storing the result (approx. 0)
The mapDispatchToProps function returns an object containing, as properties, ad-hoc wrapper functions that you defined, that perform calls to dispatch in some way that makes sense for your application. This object is then used to place these functions on the props object (the different dispatch calls are "mapped" onto these wrappers - thus the name). This is so that you can make use of dispatch in a more convenient way, using wrapper functions with names that more closely reflect what your application is doing.