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!
Feel free to correct me if anything is off here, but from my understanding of the redux docs here, it seems that store (instantiated from the createStore function) does not have an unsubscribe method store.unsubscribe(listener) to call.
Instead, it is returned from the subscribe function defined in createStore as shown below in an example breaking down the createStore function :
function createStore(reducer, preloadedState) {
let state = preloadedState
const listeners = []
function getState() {
return state
}
function subscribe(listener) {
listeners.push(listener)
return function unsubscribe() {
const index = listeners.indexOf(listener)
listeners.splice(index, 1)
}
}
function dispatch(action) {
state = reducer(state, action)
listeners.forEach(listener => listener())
}
dispatch({ type: '@@redux/INIT' })
return { dispatch, subscribe, getState }
}
So, when we assign our named function expression (unsubscribe) as the return value of createStore(reducer), we then can then access it later through unsubscribe() .
However, I’m confused as to why
store.subscribe(listener)
and
const unsubscribe = store.subscribe(() => console.log('State after dispatch: ', store.getState()) )
both seem to instantiate the subscription to the store. I thought that in the latter case, we are simply creating a named function expression named ‘unsubscribe’ and not directly calling store.subscribe().
// lightSwitchReducer(), toggle(), and store omitted...
const reactToChange = () => {
console.log(`The light was switched ${store.getState()}!`);
}
const unsubscribe = store.subscribe(reactToChange);
store.dispatch(toggle());
// reactToChange() is called, printing:
// 'The light was switched off!'
store.dispatch(toggle());
// reactToChange() is called, printing:
// 'The light was switched on!'
unsubscribe();
// reactToChange() is now unsubscribed
store.dispatch(toggle());
// no print statement!
console.log(store.getState()); // Prints 'off
These are the parts that I don’t understand:
Isn’t this the way to subscribe a change listener to the store? store.subscribe(reactToChange);
Then why are we using it as an unsubscribe function?
Why is it that when we declare this line of code… store.dispatch(toggle());
…reactToChange() is being called?
I’d really appreciate it if someone clears these things.
By setting store.subscribe(reactToChange) we are saying ‘whenever a change/event is detected perform an action’ - subscribe() is a method that listens for events and in this case the function reactToChange() is the action being performed. When you declare store.dispatch(toggle() you are changing something - the state is being toggled. When that happens subscribe() detects it and calls reactToChange().
As for your first question, I’m not sure. Unless subscribe() method itself toggles between being on and off, so every time you call it just swaps. In that case declaring unsubscribe() might just be to avoid confusion??
PS. This is my first time trying to answer a question in the forum instead of just asking them - if anyone spots any errors please let me know.
The implementation of unsubcribe isn’t intuitive but, as you’d expect, it’s obvious when you know! So here goes: -
This code sets-up aFunction() to be called whenever a change to the state happens ie. aFunction() becomes a ‘subscribed listener’ →
store.subscribe(aFunction);
This next code does exactly the same but, in addition, creates a variable called myUnsubscribe, which is a function that can be called to undo that subscription →
const myUnsubscribe = store.subscribe(aFunction);
That happens because when you call store.subscribe() it returns unsubscribe functionality, which can be captured into a variable, in this example I’ve used myUnsubscribe but you can call it any valid function name.
Given the ambiguity, how about →
when the developers of the language were deciding on how they would offer us the way to unsubscribe, they settled on returning a function from the call to subscribe. This means that whenever you call →
store.subscribe(aFunction);
it returns a function that you will use to unsubscribe the listener. To gain access to that function, you can put it into a constant like this →
const myUnsubscribe = store.subscribe(aFunction);
then, when you need to unsubscribe, call it like you would any function →
myUnsubscribe();
NB: I have used the name ‘myUnsubscribe’ here but you can use any name. If you called your constant ‘releaseSubscription’ you’d declare it like this →