首页 > 解决方案 > 如何将类组件转换为函数组件

问题描述

我一直在我的应用程序中使用 Expo Pedometer,我决定将其转换为功能组件,因为我想使用钩子。我已经尝试过更改代码,但遇到了一些问题(错误)我猜这与this._subscription不知道用什么替换它或如何在函数中编写该部分有关

Expo链接到计步器https://docs.expo.io/versions/v40.0.0/sdk/pedometer/

错误代码

[Sun Dec 20 2020 19:03:41.493]  WARN     Possible Unhandled Promise Rejection (id: 0):
TypeError: 'checking' is not a function
TypeError: 'checking' is not a function
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:159733:29)
    at tryCallOne (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:27645:16)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:27746:27)
    at apply (native)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31297:26)
    at _callTimer (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31185:17)
    at _callImmediatesPass (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31224:17)
    at callImmediates (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31441:33)
    at __callImmediates (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3325:35)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3111:34)
    at __guard (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3308:15)
    at flushedQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3110:21)
    at invokeCallbackAndReturnFlushedQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3103:33)

[Sun Dec 20 2020 19:03:41.697]  WARN     Possible Unhandled Promise Rejection (id: 1):
TypeError: '0' is not a function
TypeError: '0' is not a function
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:159745:22)
    at tryCallOne (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:27645:16)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:27746:27)
    at apply (native)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31297:26)
    at _callTimer (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31185:17)
    at _callImmediatesPass (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31224:17)
    at callImmediates (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:31441:33)
    at __callImmediates (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3325:35)
    at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3111:34)
    at __guard (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3308:15)
    at flushedQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3110:21)
    at invokeCallbackAndReturnFlushedQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:3103:33)

代码

import React, { useState, useEffect } from "react";
import { Text, View } from "react-native";
import { Pedometer } from "expo-sensors";
import { Feather } from "@expo/vector-icons";

export default function Home({ navigation }) {
  const [isPedometerAvailable] = useState("checking");
  const [currentStepCount] = useState(0);
  const [pastStepCount] = useState(0);

  useEffect(() => {
    subscribe();
    unsubscribe();
  }, []);

  const subscribe = () => {
    this._subscription = Pedometer.watchStepCount((result) => {
      currentStepCount(result.step);
    });

    Pedometer.isAvailableAsync().then(
      (result) => {
        isPedometerAvailable(String(result));
      },
      (error) => {
        isPedometerAvailable("could not get isPedometerAvailable" + error);
      }
    );

    const end = new Date();
    const start = new Date();
    start.setDate(end.getDate() - 1);
    Pedometer.getStepCountAsync(start, end).then(
      (result) => {
        pastStepCount(result.steps);
      },
      (error) => {
        pastStepCount("could not get stepCount" + error);
      }
    );
  };

  const unsubscribe = () => {
    this._subscription && this._subscription.remove();
    this._subscription = null;
  };

  return (
    <View style={{ flex: 1 }}>
        <Text style={{ fontSize: 40, fontWeight: "700" }}>Steps</Text>
        <Text style={{ fontSize: 20, fontStyle: "italic" }}>
          {currentStepCount}
        </Text>
      </View>
  );
}

标签: javascriptreact-nativeexpo

解决方案


这是我为此创建的世博小吃的链接:

这是代码:

import React, {useState, useEffect} from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Pedometer } from 'expo-sensors';

export default function App() {
  const [isPedometerAvailable, setIsPedometerAvailable] = useState('checking');
  const [pastStepCount, setPastStepCount] = useState(0);
  const [currentStepCount, setCurrentStepCount] = useState(0);

  let _subscription;

  const _subscribe = () => {
    _subscription = Pedometer.watchStepCount(result => {
      setCurrentStepCount(result.steps);
    });

    Pedometer.isAvailableAsync().then(
      result => {
        setIsPedometerAvailable(result);
      },
      error => {
        setIsPedometerAvailable('Could not get isPedometerAvailable: ' + error);
      }
    );

    const end = new Date();
    const start = new Date();
    start.setDate(end.getDate() - 1);
    Pedometer.getStepCountAsync(start, end).then(
      result => {
        setPastStepCount(result.steps);
      },
      error => {
        setPastStepCount('Could not get stepCount: ' + error);
      }
    );
  };

  const _unsubscribe = () => {
    _subscription && _subscription.remove();
    _subscription = null;
  };


  useEffect(()=>{
    _subscribe();
    return ()=> _unsubscribe();
  },[])

    return (
      <View style={styles.container}>
        <Text>Pedometer.isAvailableAsync(): {isPedometerAvailable}</Text>
        <Text>Steps taken in the last 24 hours: {pastStepCount}</Text>
        <Text>Walk! And watch this go up: {currentStepCount}</Text>
      </View>
    );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 15,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

推荐阅读