我有React Native应用程序,我从得到的数据API通过fetch。我创建了从API. 我需要每 5 秒重新渲染一次。为此,我将我的自定义钩子包装到 setInterval 并且在我的应用程序变得非常缓慢并且当我导航到另一个屏幕时我收到此错误:
无法对卸载的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。
你能告诉我如何解决这个错误,哪种方法是最好的方法setInterval,因为我认为我的方法不好。
我的自定义钩子:
export const useFetch = url => {
const [state, setState] = useState({ data: null, error: false, loading: true })
useEffect(() => {
setInterval(() => {
setState(state => ({ data: state.data, error: false, loading: true }))
fetch(url)
.then(data => data.json())
.then(obj =>
Object.keys(obj).map(key => {
let newData = obj[key]
newData.key = key
return newData
})
)
.then(newData …Run Code Online (Sandbox Code Playgroud) 我正在react-native-testing-library用来测试我的 react-native 组件。我有一个组件(为了这篇文章,它已经被过度简化了):
export const ComponentUnderTest = () => {
useEffect(() => {
__make_api_call_here_then_update_state__
}, [])
return (
<View>
__content__goes__here
</View>
)
}
Run Code Online (Sandbox Code Playgroud)
这是我的(简化版)component.spec.tsx:
import { render, act } from 'react-native-testing-library';
import { ComponentUnderTest } from './componentundertest.tsx';
test('it updates content on successful call', () => {
let root;
act(() => {
root = render(<ComponentUnderTest />); // this fails with below error message
});
expect(...);
})
Run Code Online (Sandbox Code Playgroud)
现在,当我运行此代码时,出现此错误:
Can't access .root on unmounted test renderer
我什至不知道这个错误消息是什么意思。我遵循了react-native-testing-library有关如何使用 …
我有一个 Formik 表单,需要根据通过路由器传递的信息动态更改。我需要运行一个 graphQL 查询来检索一些数据并用检索到的数据填充表单。我能够设置表单并检索数据,但我无法弄清楚如何在 useEffect 挂钩中为基础表单设置字段值。我觉得我错过了一些重要的部分来访问 Formik 上下文,但我无法从文档中找到它。
任何帮助都会很棒。
import React, { useState, useEffect } from "react";
import Router, { useRouter } from "next/router";
import Container from "react-bootstrap/Container";
import { Field, Form, FormikProps, Formik } from "formik";
import * as Yup from "yup";
import { useLazyQuery } from "@apollo/react-hooks";
import { GET_PLATFORM } from "../graphql/platforms";
export default function platformsForm(props) {
const router = useRouter();
// grab the action requested by caller and the item to be updated (if applicable) …Run Code Online (Sandbox Code Playgroud) 我看到有人使用 0 而不是空数组作为 useEffect 中的第二个参数。
所以代替
useEffect(() => {
console.log('Run once');
}, []);
Run Code Online (Sandbox Code Playgroud)
它是
useEffect(() => {
console.log('Run once');
}, 0);
Run Code Online (Sandbox Code Playgroud)
它似乎具有相同的效果,所以我想知道他为什么使用它?
根据您的评估方式,空数组被视为 0。例如[] == 0是真的,但是[] === 0是假的。所以也许在这种情况下,引擎盖下没有严格的比较,如果使用 0 也没有关系。
只是按照反应文档我会使用一个空数组。
反应文档:
如果您只想运行效果并仅将其清理一次(在装载和卸载时),您可以传递一个空数组 ([]) 作为第二个参数。这告诉 React 你的 effect 不依赖于来自 props 或 state 的任何值,所以它永远不需要重新运行。这不是作为特殊情况处理的——它直接遵循依赖项数组的工作方式。
我想知道0使用 over是否是一个可能更简洁的二进制参数[],或者 using0是否是一种不好的做法,或者它是否无关紧要并且[]只是首选的 React 约定?
谢谢。
我创建了一个全新的反应应用程序来自己测试这个,因为我的一个朋友面临这个问题。App.js 代码 ->
function App() {
useEffect(() => {
console.log('on init gets called');
}, []);
return (
<>
Hello my first react app
</>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
应用程序中不存在其他组件。以下是index.js代码->
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)
当我们第一次加载应用程序时,useEffect 中存在的 console.log 会打印两次。我希望它只打印一次。
我知道使用钩子时的传统方法是使用钩子获取数据useEffect。但是为什么我不能直接在功能组件中调用axios而不是hook然后设置数据呢。
基本上,我想问这样做有什么问题:
const [users, setUsers] = useState(null);
axios.get("some api call")
.then(res => setUsers(res.data))
Run Code Online (Sandbox Code Playgroud)
在这里,我不使用useEffect,会出什么问题吗?
我正在制作一个自定义下拉列表,允许在下拉列表中推送新项目。由于某种原因,useEffect 不会在状态更改时触发,但会在初始渲染时触发。我很确定我错过了一些小东西,但看不到它。当用户单击与“addNewOptionToTree”方法关联的按钮时,应推送新项目。然后,categoryList 应在下拉列表中显示新项目。控制台日志被触发并且新的 arr 出现......有什么想法吗?
以上返回:
const [newOption, setNewOption] = useState('')
const [categoryList, setCategoryList] = useState(["Calendars", "Meetings", "Apostrophes work!"])
useEffect(() => {
console.log("categoryList::::::::::::::::", categoryList)
}, [categoryList]);
function addNewOptionToTree() {
console.log('category:', categoryList);
console.log('newOption:', newOption);
const categoryListArr = categoryList
categoryListArr.push(newOption)
setCategoryList(categoryListArr)
console.log("category:", categoryListArr);
}
Run Code Online (Sandbox Code Playgroud)
在返回块中:
<div className='dropDownList'>
<div className='listItem' key={'add-item-key'}>
<Input
type='text'
label=''
value={newOption}
placeholder='Add New Category'
onChange={val => setNewOption(val)}
/>
<div className='icon-add-contain dropdown-add-btn' onClick={addNewOptionToTree}></div>
</div>
{
categoryList.length > 0 &&
categoryList.map((category, index) => (
<div className='listItem' onClick={onOptionClicked(category)} key={'level1-'+index}>
{category}
</div>
)) …Run Code Online (Sandbox Code Playgroud) 我正在做一个反应项目。我有自己的 API 来获取信息。我正在使用 useEffect 挂钩从 API 获取配置文件信息。我的问题是,当页面第一次安装时,我可以毫无问题地获取数据,但如果我刷新页面,它根本不起作用。我知道我必须为 useEffect 提供第二个参数。我尝试将配置文件作为第二个参数,甚至调度了 getCurrentProfile 函数,但是当我这样做时,它会不断地触发获取请求。如果有人能帮助我,我会很高兴。谢谢。
这是我的个人资料组件:
export const Profile = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getCurrentProfile());
}, [])
const profileReducer = useSelector((state) => state.profile);
const authReducer = useSelector((state) => state.auth);
const { profile, error, loading } = profileReducer;
const { user } = authReducer;
console.log("loading", loading)
console.log("profile", profile)
return loading && profile === null ? (
<div >
<Spinner />
</div>
) :
Run Code Online (Sandbox Code Playgroud)
这是我的个人资料操作:
export const getCurrentProfile = () …Run Code Online (Sandbox Code Playgroud) 我创建了一个应用程序来进行 React Native 研究。\n完成后,我添加了一些演示屏幕并添加了 \',react-native-onboarding-swiper\'这对我来说似乎是我发现的最简单的方法。\n我还添加了\'@react-native-async-storage/async-storage\',在添加启动屏幕之前,该应用程序可以正常工作没有AsyncStorage
这个想法是,当我们安装它并第一次打开它时,该应用程序会显示演示屏幕,然后,它会在我显示的菜单屏幕中打开。
\n再次编辑:
\n我需要纠正这种情况,以便启动画面仅在应用程序第一次启动时显示,然后它应该启动到主屏幕。\n2 - 主屏幕是我在屏幕截图中显示的屏幕,它向我显示了按钮到"Go Back"。我需要这个消失
我无法使用 headerShown: false,因为在应用程序具有的其他屏幕中,如果我必须有该"Go Back"按钮\n如何以最简单的方式纠正这些问题?
该应用程序与我在下面显示的 App.js 中的代码完美配合,但每当打开应用程序时它都会显示演示屏幕。我创建了一个条件来纠正此问题,因为我需要在第一次打开应用程序时增加显示的演示屏幕。这是添加之前 App.js 的样子else if:
import "react-native-gesture-handler";\nimport React, { useEffect } from "react";\n\nimport { NavigationContainer } from "@react-navigation/native";\nimport { createStackNavigator } from "@react-navigation/stack";\nimport AsyncStorage from "@react-native-async-storage/async-storage";\nimport SplashScreen from "react-native-splash-screen";\n\nimport NuevaOrden from "./views/NuevaOrden";\nimport OnboardingScreen from "./views/OnboardingScreen";\n\nconst Stack = createStackNavigator();\n\nconst App = () => {\n\n//Hide Splash screen …Run Code Online (Sandbox Code Playgroud) 正如标题所说,我设置的 localStorage 注册了对todoList数组所做的更改并JSON.stringify保存它;但是,每当我刷新页面时,数组都会返回默认[]状态。
const LOCAL_STORAGE_KEY = "task-list"
function TodoList() {
const [todoList, setTodoList] = useState([]);
useEffect(() => {
const storedList = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
if (storedList) {
setTodoList(storedList);
}
}, []);
useEffect(() => {
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList));
}, [todoList]);
Run Code Online (Sandbox Code Playgroud) use-effect ×10
reactjs ×8
javascript ×5
react-hooks ×4
react-native ×3
use-state ×2
act ×1
axios ×1
console ×1
formik ×1
frontend ×1
react-apollo ×1
react-native-testing-library ×1
react-redux ×1
setinterval ×1