Your both dispatch are called after first render so even before your second render value is 0 so your second useEffect won't be able detect change as there is no change.
Let's see what is happening in your render method
First Render:
a = 0
first useEffect: dispatch({ a : 1 })
second useEffect: dispatch({ a : 0 })
so now in your redux store a is 0.
Second Render
a = 0
first useEffect: doesn't run as there is no dependency
second useEffect: doesn't run as a hasn't changed.
Answer from Amit Chauhan on Stack OverflowYour both dispatch are called after first render so even before your second render value is 0 so your second useEffect won't be able detect change as there is no change.
Let's see what is happening in your render method
First Render:
a = 0
first useEffect: dispatch({ a : 1 })
second useEffect: dispatch({ a : 0 })
so now in your redux store a is 0.
Second Render
a = 0
first useEffect: doesn't run as there is no dependency
second useEffect: doesn't run as a hasn't changed.
PLEASE, stop using
useSelector(state => state.mainReducer);
it doesn't make any sense
there should be a simple state transformation (subselection)
const a = useSelector(state => state.a)
taken directly from redux docs:
const counter = useSelector(state => state.counter)
update
you can see effect (from store change) with slightly changed component
function MyComponent(props) {
const a = useSelector(state => state.a);
const dispatch = useDispatch();
console.log('render: ', a);
useEffect(() => {
console.log('use effect: ', a);
dispatch({ type: 'A', payload: a });
}, [a])
useEffect(() => {
console.log('did mount: ', a);
dispatch({ type: 'A', payload: 1 })
}, []);
return (<View style={styles.container}>
<Text style={styles.text}>{a}</Text>
</View>);
};
It should result in log:
render: 0// initial stateuse effect: 0// first effect run- // dispatch
0... processed in store by reducer but results in the same state ...
// ... and in our rendering process we still working on an 'old'areaded from state on the beginning of render did mount: 0// 'old'a
// dispatch1... changed state in redux store.... rendered text
0
...
...//
useSelectorforces rerendering - change detectedrender: 1// latest dispatched value, processed by reducers into new state, rereaded by selectoruse effect: 1//useEffectworks AS EXPECTED as an effect ofachange- .... rendered text
1
...
...
- no more rerenderings - latest dispach not changed state
Of course dispatch from other component will force update in this component ... if value will be different.
Hello all, i'm a fairly noob developper and new to react.
Is it possible to have a useEffect to only run when the dependency array changes and not at mount ?
Also i can't explain why but it seems to me a bad use of useEffect, is there a better way to achieve this ? Thanks