There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply () below.
If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.
Join the Discussion. Help a fellow learner on their journey.
Ask or answer a question about this exercise by clicking reply () below!
You can also find further discussion and get answers to your questions over in Language Help.
Agree with a comment or answer? Like () to up-vote the contribution!
Does anyone else find it confusing that Codecademy hops around between redux libraries (redux, react-redux, reduxToolKit)?
It doesnt seem clear at this point whether these libraries are 100% mutually exclusive or can be used together in some ways?
It appeared as though Redux ToolKit was the most effective way to configure the store, yet in this exercise we revert back to regular redux to implement the middleware.
Redux middleware are written using a triply-nested function structure that looks like const middleware = storeAPI => next => action => {} , rather than a single function that looks like const middleware = (storeAPI, next, action) => {} . There’s a few reasons for this.
One is that “currying” functions is a standard functional programming technique, and Redux was explicitly intended to use functional programming principles in its design. Another is that currying functions creates closures where you can declare variables that exist for the lifetime of the middleware (which could be considered a functional equivalent to instance variables that exist for the lifetime of a class instance). Finally, it’s simply the approach that was chosen when Redux was initially designed.
The curried function signature of declaring middleware is deemed unnecessary by some, because both store and next are available when the applyMiddleware function is executed. This issue has been determined to not be worth introducing breaking changes, as there are now hundreds of middleware in the Redux ecosystem that rely on the existing middleware definition.
Hi there, I find it confusing in this modul “Write Your Own Middleware” that console.log(StoreAPI.getState()) has not been logged but instead visually hided. What is it and why is it? CODE Snippet might not work but when you do it in your own workspace it does.
import { createStore, applyMiddleware } from 'redux';
const messageReducer = (state = '', action) => {
if (action.type === 'NEW_MESSAGE') {
return action.payload;
} else {
return state;
}
}
// Paste the logger function here.
const logger = storeAPI => next => action => {
// do stuff here
console.log(storeAPI.getState());
console.log("Gap created")
console.log(storeAPI.getState());
const nextState = next(action);
console.log(storeAPI.getState());
console.log(nextState)
console.log(storeAPI.getState());
return nextState;
};
const store = createStore(messageReducer, '', applyMiddleware(logger));
store.dispatch({
type: 'NEW_MESSAGE',
payload: 'I WROTE A MIDDLEWARE'
})
You get a blank line when you log the storeAPI.getState() because the state is a blank space ' '. You can see the second parameter in the call to createStore(messageReducer, '', applyMiddleware(logger)); that you set the initialState to a blank space.
I got the same problem as you, and I thought that I was the only one who saw their mistake.
But now I have another question. Why do we have to return the nextState variable even after we called next(action)?
I see that the program works very well even if we comment the last line with the return statement, because we passed the action to the next middleware in the pipeline.
Does anyone notice that earlier it was taught that createStore() can have only one parameter, i.e, root reducer. then how in this lesson we are passing three arguments. Does anyone know, where am I mistaken?
In your solution, you are not returning the new state, but the action. Same as in the, IMHO, buggy excersise, which is not the functionality expected from this logger function.
I refactor the code to actually achieve what this looger function is supposed to do. Please check the comments inline:
import { createStore, applyMiddleware } from 'redux';//createStore is deprecated. configureStore must be used instead according to Redux Toolkit. But we will keep it like this to stay true to the outdated example provided
const messageReducer = (state = 'Default State', action) => {// In order for the first storeAPI.getState() log something more than an empty line (counfusing), defalut state is set to the string 'Default state'. The redundant default state empty string in createStore a few lines after has been removed too.
if (action.type === 'NEW_MESSAGE') {
return action.payload;
} else {
return state;
}
}
// Paste the logger function here > CALLING THIS "THE MIDDLEWARE LOGGER FUNCTION" WOULD HAVE MAKE EVERYTHING MORE CLEAR
const logger = storeAPI => next => action => {
console.log(storeAPI.getState())// This will log the default state
next(action);//dispatches action type:'NEW_MESSAGE', updating state, since this is the last (and only) reducer in the pipeline
const nextState = (store.getState())// saves the updated state to a variable that we can log and return. Not actually needed, but I guess is an abstraction to make the code easier to read. this could have been ommited and then, in the return statement, return storeAPI.getState()
console.log(nextState)// Logs current state. Same as before: could have been written console.log(storeAPI.getState())
return nextState;// returns the new update state. Could have been written return storeAPI.getState(). I DON'T UNDERSTAND WHY THIS MIDDLEWARE HAS TO RETURN ANYTHING. IF THERE WERE A NEXT MIDDLEWARE IN THE PIPELINE, IT WOULDN'T SEEM TO BE ABLE TO USE IT.
};
const store = createStore(messageReducer, applyMiddleware(logger));// Default state (second argument) removed. This was not explained before, nor needed in this exercise
store.dispatch({type: 'NEW_MESSAGE', payload: 'I WROTE A MIDDLEWARE'})