Error: Invalid hook call. Hooks can only be called inside of the body of a function component in React Native
Error: Invalid hook call. Hooks can only be called inside of the body of a function component in React Native
我正在尝试在组件中使用 useSelector,但我仍然收到错误提示: Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
backgroundTasks.js:
import axios from "axios";
import AsyncStorage from '@react-native-community/async-storage';
import { baseURL, mlURL } from "../../constants";
import BackgroundFetch from "react-native-background-fetch";
import { useSelector } from "react-redux";
import { showNotification, handleScheduleNotification, handleCancel } from "./notification.android";
const getLatestNotifications = async (headers, user_id) => {
const Link = `${baseURL}/api/push-notifications`;
console.log("Push notification Link is", Link);
try {
let data = await axios
.get(
Link,
{ headers: headers }
);
if (data.data.response) {
console.log("Recieved notification response", data.data.response);
return data.data.response;
}
else {
return [];
}
} catch (err) {
console.log("Notifications error", err);
return [];
}
}
//In startTask I want to use useSeletor but I am getting error.
const startTask = async (task = "notifications") => {
console.log("Background task started");
console.log('background');
const token = await AsyncStorage.getItem("token");
const user_id = await AsyncStorage.getItem("user_id");
const userName = await AsyncStorage.getItem("name");
const notificationsUnReadNumber = useSelector((state) => state.notification.notificationCount); //Here
console.log(notificationsUnReadNumber);
const apiHeaders = {
'x-access-token': token,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
'Accept': 'application/json, text/plain, */*',
};
if (task == "notifications" && token) {
let notifications = await getLatestNotifications(apiHeaders, user_id);
console.log("Get Latest Notifications data", notifications);
if (notifications && notifications.length > 0 && notificationsUnReadNumber !==0) {
console.log('inside notification');
notifications.forEach((notification) => {
showNotification(notification.title, notification.content, String(notification._id));
});
}
}
};
const inititalizeBackgroundTasks = async () => {
const onEvent = async (taskId) => { //This task will run when app is not terminated (foreground/background)
console.log('[BackgroundFetch] task: ', taskId);
// Do your background work...
console.log("Task background called")
console.log("Received background-fetch event: ", taskId);
startTask("notifications");
BackgroundFetch.finish(taskId);
}
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgorundFetch.finish(taskId)
const onTimeout = async (taskId) => {
console.warn('[BackgroundFetch] TIMEOUT task: ', taskId);
BackgroundFetch.finish(taskId);
}
let status = await BackgroundFetch.configure({
minimumFetchInterval: 15, //Run Task every 15 minutes
// Android options
forceAlarmManager: true, // <-- Set true to bypass JobScheduler.
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_NONE, // Default
requiresCharging: false, // Default
requiresDeviceIdle: false, // Default
requiresBatteryNotLow: false, // Default
requiresStorageNotLow: false // Default
}, onEvent, onTimeout);
console.log('[BackgroundFetch] configure status: ', status);
};
export { inititalizeBackgroundTasks};
如果我必须将其作为一个组件,那么如何将 backgroundTasks
导出为 default
和 export {inititalizeBackgroundTasks}
正常?
我只想导出一个名为 inititalizeBackgroundTasks 的组件,并在我的组件中将其他组件用作函数,所以如果我以错误的方式使用 useSelector,我该如何使用?
在调用 startTask()
的组件中导入 useSelector
并将其添加为第二个参数,如 startTask('notifications', useSelector)
。这应该可以解决您的问题。
仅从 React 函数调用挂钩
✅ 从 React 函数组件中调用 Hooks。
✅ 从自定义 Hooks 调用 Hooks
在 documentation.
中了解有关 Hook 规则 的更多信息
我希望这项工作可以帮助你(正如你上面提到的)我们创建 backgroundTasks export default 作为一个功能组件,所以我们可以使用 react hooks。
import { useEffect } from "react";
import axios from "axios";
import AsyncStorage from "@react-native-community/async-storage";
import { baseURL, mlURL } from "../../constants";
import BackgroundFetch from "react-native-background-fetch";
import { useSelector } from "react-redux";
import {
showNotification,
handleScheduleNotification,
handleCancel,
} from "./notification.android";
const getLatestNotifications = async (headers, user_id) => {
const Link = `${baseURL}/api/push-notifications`;
console.log("Push notification Link is", Link);
try {
let data = await axios.get(Link, { headers: headers });
if (data.data.response) {
console.log("Recieved notification response", data.data.response);
return data.data.response;
} else {
return [];
}
} catch (err) {
console.log("Notifications error", err);
return [];
}
};
//In startTask I want to use useSeletor but I am getting error.
const startTask = async (task = "notifications", notificationsUnReadNumber) => {
console.log("Background task started");
console.log("background");
const token = await AsyncStorage.getItem("token");
const user_id = await AsyncStorage.getItem("user_id");
const userName = await AsyncStorage.getItem("name");
console.log(notificationsUnReadNumber);
const apiHeaders = {
"x-access-token": token,
"User-Agent":
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0",
Accept: "application/json, text/plain, */*",
};
if (task == "notifications" && token) {
let notifications = await getLatestNotifications(apiHeaders, user_id);
console.log("Get Latest Notifications data", notifications);
if (
notifications &&
notifications.length > 0 &&
notificationsUnReadNumber !== 0
) {
console.log("inside notification");
notifications.forEach((notification) => {
showNotification(
notification.title,
notification.content,
String(notification._id)
);
});
}
}
};
export const inititalizeBackgroundTasks = async (notificationsUnReadNumber) => {
let status = await BackgroundFetch.configure(
{
minimumFetchInterval: 15, //Run Task every 15 minutes
// Android options
forceAlarmManager: true, // <-- Set true to bypass JobScheduler.
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_NONE, // Default
requiresCharging: false, // Default
requiresDeviceIdle: false, // Default
requiresBatteryNotLow: false, // Default
requiresStorageNotLow: false, // Default
},
async (taskId) => {
//This task will run when app is not terminated (foreground/background)
console.log("[BackgroundFetch] task: ", taskId);
// Do your background work...
console.log("Task background called");
console.log("Received background-fetch event: ", taskId);
startTask("notifications", notificationsUnReadNumber);
BackgroundFetch.finish(taskId);
},
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgorundFetch.finish(taskId)
async (taskId) => {
console.warn("[BackgroundFetch] TIMEOUT task: ", taskId);
BackgroundFetch.finish(taskId);
}
);
console.log("[BackgroundFetch] configure status: ", status);
};
const backgroundTasks = () => {
const notificationsUnReadNumber = useSelector(
(state) => state.notification.notificationCount
); //Here
useEffect(() => {
if (notificationsUnReadNumber) {
inititalizeBackgroundTasks(notificationsUnReadNumber);
}
}, [notificationsUnReadNumber]);
};
export default backgroundTasks;
我正在尝试在组件中使用 useSelector,但我仍然收到错误提示: Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
backgroundTasks.js:
import axios from "axios";
import AsyncStorage from '@react-native-community/async-storage';
import { baseURL, mlURL } from "../../constants";
import BackgroundFetch from "react-native-background-fetch";
import { useSelector } from "react-redux";
import { showNotification, handleScheduleNotification, handleCancel } from "./notification.android";
const getLatestNotifications = async (headers, user_id) => {
const Link = `${baseURL}/api/push-notifications`;
console.log("Push notification Link is", Link);
try {
let data = await axios
.get(
Link,
{ headers: headers }
);
if (data.data.response) {
console.log("Recieved notification response", data.data.response);
return data.data.response;
}
else {
return [];
}
} catch (err) {
console.log("Notifications error", err);
return [];
}
}
//In startTask I want to use useSeletor but I am getting error.
const startTask = async (task = "notifications") => {
console.log("Background task started");
console.log('background');
const token = await AsyncStorage.getItem("token");
const user_id = await AsyncStorage.getItem("user_id");
const userName = await AsyncStorage.getItem("name");
const notificationsUnReadNumber = useSelector((state) => state.notification.notificationCount); //Here
console.log(notificationsUnReadNumber);
const apiHeaders = {
'x-access-token': token,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
'Accept': 'application/json, text/plain, */*',
};
if (task == "notifications" && token) {
let notifications = await getLatestNotifications(apiHeaders, user_id);
console.log("Get Latest Notifications data", notifications);
if (notifications && notifications.length > 0 && notificationsUnReadNumber !==0) {
console.log('inside notification');
notifications.forEach((notification) => {
showNotification(notification.title, notification.content, String(notification._id));
});
}
}
};
const inititalizeBackgroundTasks = async () => {
const onEvent = async (taskId) => { //This task will run when app is not terminated (foreground/background)
console.log('[BackgroundFetch] task: ', taskId);
// Do your background work...
console.log("Task background called")
console.log("Received background-fetch event: ", taskId);
startTask("notifications");
BackgroundFetch.finish(taskId);
}
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgorundFetch.finish(taskId)
const onTimeout = async (taskId) => {
console.warn('[BackgroundFetch] TIMEOUT task: ', taskId);
BackgroundFetch.finish(taskId);
}
let status = await BackgroundFetch.configure({
minimumFetchInterval: 15, //Run Task every 15 minutes
// Android options
forceAlarmManager: true, // <-- Set true to bypass JobScheduler.
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_NONE, // Default
requiresCharging: false, // Default
requiresDeviceIdle: false, // Default
requiresBatteryNotLow: false, // Default
requiresStorageNotLow: false // Default
}, onEvent, onTimeout);
console.log('[BackgroundFetch] configure status: ', status);
};
export { inititalizeBackgroundTasks};
如果我必须将其作为一个组件,那么如何将 backgroundTasks
导出为 default
和 export {inititalizeBackgroundTasks}
正常?
我只想导出一个名为 inititalizeBackgroundTasks 的组件,并在我的组件中将其他组件用作函数,所以如果我以错误的方式使用 useSelector,我该如何使用?
在调用 startTask()
的组件中导入 useSelector
并将其添加为第二个参数,如 startTask('notifications', useSelector)
。这应该可以解决您的问题。
仅从 React 函数调用挂钩
✅ 从 React 函数组件中调用 Hooks。
✅ 从自定义 Hooks 调用 Hooks
在 documentation.
中了解有关 Hook 规则 的更多信息
我希望这项工作可以帮助你(正如你上面提到的)我们创建 backgroundTasks export default 作为一个功能组件,所以我们可以使用 react hooks。
import { useEffect } from "react";
import axios from "axios";
import AsyncStorage from "@react-native-community/async-storage";
import { baseURL, mlURL } from "../../constants";
import BackgroundFetch from "react-native-background-fetch";
import { useSelector } from "react-redux";
import {
showNotification,
handleScheduleNotification,
handleCancel,
} from "./notification.android";
const getLatestNotifications = async (headers, user_id) => {
const Link = `${baseURL}/api/push-notifications`;
console.log("Push notification Link is", Link);
try {
let data = await axios.get(Link, { headers: headers });
if (data.data.response) {
console.log("Recieved notification response", data.data.response);
return data.data.response;
} else {
return [];
}
} catch (err) {
console.log("Notifications error", err);
return [];
}
};
//In startTask I want to use useSeletor but I am getting error.
const startTask = async (task = "notifications", notificationsUnReadNumber) => {
console.log("Background task started");
console.log("background");
const token = await AsyncStorage.getItem("token");
const user_id = await AsyncStorage.getItem("user_id");
const userName = await AsyncStorage.getItem("name");
console.log(notificationsUnReadNumber);
const apiHeaders = {
"x-access-token": token,
"User-Agent":
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0",
Accept: "application/json, text/plain, */*",
};
if (task == "notifications" && token) {
let notifications = await getLatestNotifications(apiHeaders, user_id);
console.log("Get Latest Notifications data", notifications);
if (
notifications &&
notifications.length > 0 &&
notificationsUnReadNumber !== 0
) {
console.log("inside notification");
notifications.forEach((notification) => {
showNotification(
notification.title,
notification.content,
String(notification._id)
);
});
}
}
};
export const inititalizeBackgroundTasks = async (notificationsUnReadNumber) => {
let status = await BackgroundFetch.configure(
{
minimumFetchInterval: 15, //Run Task every 15 minutes
// Android options
forceAlarmManager: true, // <-- Set true to bypass JobScheduler.
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_NONE, // Default
requiresCharging: false, // Default
requiresDeviceIdle: false, // Default
requiresBatteryNotLow: false, // Default
requiresStorageNotLow: false, // Default
},
async (taskId) => {
//This task will run when app is not terminated (foreground/background)
console.log("[BackgroundFetch] task: ", taskId);
// Do your background work...
console.log("Task background called");
console.log("Received background-fetch event: ", taskId);
startTask("notifications", notificationsUnReadNumber);
BackgroundFetch.finish(taskId);
},
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgorundFetch.finish(taskId)
async (taskId) => {
console.warn("[BackgroundFetch] TIMEOUT task: ", taskId);
BackgroundFetch.finish(taskId);
}
);
console.log("[BackgroundFetch] configure status: ", status);
};
const backgroundTasks = () => {
const notificationsUnReadNumber = useSelector(
(state) => state.notification.notificationCount
); //Here
useEffect(() => {
if (notificationsUnReadNumber) {
inititalizeBackgroundTasks(notificationsUnReadNumber);
}
}, [notificationsUnReadNumber]);
};
export default backgroundTasks;