Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument of type 'void' is not assignable to parameter of type '(state: AppStateStatus) => void' #33151

Closed
VictorioMolina opened this issue Feb 20, 2022 · 7 comments

Comments

@VictorioMolina
Copy link

Description

I am trying to remove my AppState listener subscription, but I am getting the following es-lint warning:

Argument of type 'void' is not assignable to parameter of type '(state: AppStateStatus) => void'

I am just doing this:

  useEffect(() => {
    const unsubAppState = AppState.addEventListener(
      "change",
      handleOnAppStateChange
    );

    return () => {
      AppState.removeEventListener("change", unsubAppState);
    };
  }, [handleOnAppStateChange, handleNetworkErrors]);

I know that the removeEventListener method is deprecated, but the .remove() is not a method of unsubAppState... in fact, AppState.addEventListener seems to be returning void.

export interface AppStateStatic {
    currentState: AppStateStatus;

    /**
     * Add a handler to AppState changes by listening to the change event
     * type and providing the handler
     */
    addEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;

    /**
     * Remove a handler by passing the change event type and the handler
     */
    removeEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;
}

Version

0.64.3

Output of npx react-native info

System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
Memory: 4.65 GB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 16.13.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.4.0 - /usr/local/bin/npm
Watchman: 2021.06.07.00 - /usr/local/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK:
Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
Android SDK: Not Found
IDEs:
Android Studio: Not Found
Xcode: 12.4/12D4e - /usr/bin/xcodebuild
Languages:
Java: Not Found
npmPackages:
@react-native-community/cli: Not Found
react: ^17.0.2 => 17.0.2
react-native: https://github.com/expo/react-native/archive/sdk-44.0.0.tar.gz => 0.64.3
react-native-macos: Not Found

Steps to reproduce

  useEffect(() => {
    const unsubAppState = AppState.addEventListener(
      "change",
      handleOnAppStateChange
    );

    return () => {
      AppState.removeEventListener("change", unsubAppState);
    };
  }, [handleOnAppStateChange, handleNetworkErrors]);

Snack, code example, screenshot, or link to a repository

No response

@t42merli
Copy link

t42merli commented Feb 24, 2022

It's because you are on react-native 0.64 and not 0.67 where AppState.addEventListener returns something and AppState.removeEventListener() is deprecated, use AppState.removeEventListener("change", handleOnAppStateChange) or update

@editstudio
Copy link

How should this work for react-native 0.65 where removeEventListener has been depreciated, but AppState.addEventListener return void?

@VictorioMolina
Copy link
Author

Any updates?

@VictorioMolina
Copy link
Author

VictorioMolina commented Jun 19, 2022

@editstudio @t42merli did u find any solution? If you check the example in the documentation and modify its useEffect to:

  useEffect(() => {
    const subscription = AppState.addEventListener("change", nextAppState => {
      if (
        appState.current.match(/inactive|background/) &&
        nextAppState === "active"
      ) {
        console.log("App has come to the foreground!");
      }

      appState.current = nextAppState;
      setAppStateVisible(appState.current);
      console.log("AppState", appState.current);
    });

    console.log(typeof subscription.remove);  // <--- ERROR!

    return () => {
      subscription.remove();
    };
  }, []);

you can see .remove() is not a property of void (as expected). Also, after upgrading to the last react native version (0.68.2), I am getting the warning

EventEmitter.removeListener('appStateDidChange', ...): Method has been deprecated. Please instead use remove() on the subscription returned by EventEmitter.addListener.

while removeEventListener is not marked as @deprecated in the core, and addEventListener returns void.

export interface AppStateStatic {
    currentState: AppStateStatus;

    /**
     * Add a handler to AppState changes by listening to the change event
     * type and providing the handler
     */
    addEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;

    /**
     * Remove a handler by passing the change event type and the handler
     */
    removeEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;
}

Wtf? Am I missing something?

@AntoineDoubovetzky
Copy link
Contributor

@VictorioMolina The removeEventListener method takes the listener as 2nd argument (in your case the handleOnAppStateChange function). So you should call:

AppState.removeEventListener("change", handleOnAppStateChange);

@ernstluring
Copy link

@VictorioMolina I had the exact same issue as you, but then I remembered I also needed to update the react-native typings to the correct version.

@namnh-0652
Copy link

@ernstluring is correct, you also need to update the types/react-native also

"devDependencies": {
 ...
 "@types/react-native": "^0.68.2",
}

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

No branches or pull requests

7 participants