Hey all I have finally updated my React Native App which also comes with an update of React to 19.2.0.
That version of React adds/activates a new ESLint rule named react-hooks/set-state-in-effect. Which does make sense to enforce I guess and I did found a couple of places where I was able save one or two unnecessary re-renders but here I really am not sure what the best fix is. Here is a simplified but reproducible example:
export default function SyncIndicator({ loading }) {
const [visible, setVisible] = useState(false);
const opacity = useAnimatedValue(0);
useEffect(() => {
if (loading) {
setVisible(true); // react-hooks/set-state-in-effect violation
const animation = Animated.timing(opacity, { toValue: 1, duration: 200 });
animation.start();
} else {
const animation = Animated.timing(opacity, { toValue: 0, duration: 200 });
animation.start(() => {
setVisible(false); // this is fine as its async
});
}
}, [loading, opacity]);
if (visible) {
return (
<Animated.View style={{ opacity }}>
<ActivityIndicator color={'#194159'} />
</Animated.View>
);
} else {
return null;
}
}
Theoretically this would just render it three times I believe which is not perfect, but wouldn't at-least end up being an infinite loop.
Honestly from UX standpoint it would be even better to get rid of visible and enable pointerEvents only if loading is true to make it pass down events if half opaque. It would even make the code cleaner, but I also do want to know now how people on here would fix it.
Did anybody else found themselves with ESLint screaming at you after updating React? Is there a clean fix to this?
Rule Documentation: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect