Skip to content

Incompatibility with React useEffect #491

Description

@JonAbrams

I'm using @preact/signals-react along with the babel transformer and am running into an issue with React's useEffect. The official react lint rule react-hooks/exhaustive-deps doesn't play nicely with signals.

Consider this example:

import { signal } from '@preact/signals-react';
const countSignal = signal(0);

export function Counter({ multiplier: number }) {
  useEffect(() => {
    localStorage.setItem('countWithMultiplier', `${multiplier * countSignal.value}`);
  }, [multiple, countSignal.value]);

  return (<div>
    {multiplier * countSignal.value}
    <button onClick={() => countSignal.value++}>Add One</button>
  </div>);
}

The above will fail the react-hooks/exhaustive-deps check because countSignal.value in the list of useEffect dependencies is declared an error:

Outer scope values like 'countSignal.value' aren't valid dependencies because mutating them doesn't re-render the component

I know that there exists a useSignalEffect hook to allow a component to run side effects on a signal's change, but it's only for signals, it can't trigger on prop changes too (like in the example).

This can be worked around by assigning the value to a local variable first (const countValue = countSignal.value), but that's annoying. Plus before you even remember to do that, an eslint autofix would just silently remove the countSignal.value dependency from useEffect, leading to a potential bug.

One potential fix could be to add an optional dependency array to useSignalEffect so that it can also trigger on non-signal changes. Also, useSignalEffect isn't documented, so there's that too.

Update: Fixed example, now using a signal created out of scope of the component to reflect the actual case were the linter raises a warning.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions