I am having a subscription
, which I set up in the useEffect()
Hook. Based on a variable from the store
, I want to execute code (or not) which is also part of the body of the subscription
.
const variableFromStore = useSelector(state => state.variableFromStore);
const dispatch = useDisptach();
useEffect(() => {
const subscriptionEvent = SomeModule.AddSubscription(event => {
console.log(variableFromStore);
if(variableFromStore) {
dispatch(foo());
}
});
})
Initially, variableFromStore
is false. However, during interaction with the App (which includes unmounting the component, because the App is moved to background), it gets set to true
. Then, some time later, subscriptionEvent
gets fired.
But, when I console.log(variableFromStore)
in there, it is always false
, eventhough the redux debugger
tells me it is true
...
Is it not possible to pass a state/store
variable into a subscription?
I assume this is because I am setting up the subscription
in the useEffect()
hook, which only gets executed once. But, if I set it up like this
useEffect(() => {
const subscriptionEvent = SomeModule.AddSubscription(event => {
console.log(variableFromStore);
if(variableFromStore) {
dispatch(foo());
}
});
},[variableFromStore])
Wouldn't that reinitialize the subscription
every time variableFromStore
changes?
CodePudding user response:
If you use the useEffect with empty or without a dependency array, it will only run on the first render.
If you add the variable you want to use or run the effect on the variable's value change add that variable to the useEffect's dependency array.
Try this code down below and also check out this documentation for more.
const variableFromStore = useSelector(state => state.variableFromStore);
useEffect(() => {
const subscriptionEvent = SomeModule.AddSubscription(event => {
console.log(variableFromStore);
if(variableFromStore) {
dispatch(foo())
}
});
}, [variableFromStore])
CodePudding user response:
This happens because your useEffect callback runs only once, and the variableFromStore
is enclosed by callback closure, to fix that, redux provides another way of getting the state from the store by calling the store getState method, which returns your whole state object, so you need to import your store first, from wherever it was created, and call getState
method, this way the same last value will be returned as per using the selector, but that is not affected by closure:
import store from '...'
useEffect(() => {
const subscriptionEvent = SomeModule.AddSubscription(event => {
const { variableFromStore } = store.getState()
console.log(variableFromStore);
if(variableFromStore) {
dispatch(foo());
}
});
})