对 React 来说相对较新,遇到了一些我不确定答案的问题。如果有条件操作,useEffect与仅使用 if 语句有区别吗?
function Items() {
[setItemAdded, itemAdded] = useState(false);
if (itemAdded) {
saveData();
itemAdded = false;
}
}
Run Code Online (Sandbox Code Playgroud)
与
useEffect(() => {
if (itemAdded) {
saveData();
itemAdded = false;
}, [itemAdded]);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,当状态更新时itemAdded,它将重新渲染将调用条件语句并执行代码的组件。
在第二种情况下,由于是一个依赖项,因此每当更改itemAdded时都会调用它。itemAdded对我来说,这两种情况似乎具有相同的效果。两者有区别吗?
在我的主页中,我有类似这样的代码
{selectedTab===0 && <XList allItemList={some_list/>}
{selectedTab===1 && <YList allItemList={some_list2/>}
Run Code Online (Sandbox Code Playgroud)
现在,在 XList 中,我有这样的内容:
{props.allItemList.map(item => <XItem item={item}/>)}
Run Code Online (Sandbox Code Playgroud)
现在,在 XItem 内部,我调用 api 来获取 XItem 的图像。
现在我的问题是,当在主页中,我将选项卡从 0 切换到 1 或 1 切换到 0 时,它再次调用 XItem 中的所有 API。每当我切换选项卡时,它都会再次调用 api。我不想要这样。我已经在 XItem 中使用了 useEffect,并使用 [] 数组作为第二个参数。
我有我的后端代码,我在其中创建了一个 api 来获取 XItem 的图像。API直接返回图像而不是url,所以我不能一次调用所有api。
我需要一些解决方案,以便最大限度地减少 api 调用。感谢帮助。
我正在使用 React 构建一个简单的时钟应用程序。目前该countDown()功能有效,但我希望用户能够通过按下按钮来停止/启动时钟。我有一个名为的状态布尔值,paused当用户单击按钮时该状态布尔值会反转。问题在于,在 的值反转后,对传递给的函数内部paused的引用似乎正在访问 的默认值,而不是更新后的值。pausedcountDown()setInterval()paused
function Clock(){
const [sec, setSecs] = useState(sessionLength * 60);
const [paused, setPaused] = useState(false);
const playPause = () => {
setPaused(paused => !paused);
};
const countDown = () => {
if(!paused){
setSecs(sec => sec - 1)
}
}
useEffect(() => {
const interval = setInterval(() => {
countDown();
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
Run Code Online (Sandbox Code Playgroud)
setState()我假设它与 React 中调用的异步性质和/或使用正则表达式时范围/上下文的性质有关。然而,我无法通过阅读与这些概念相关的文档来确定发生了什么。
我可以想到一些解决方法,让我的应用程序能够按需要运行。但是我想了解我当前的方法有什么问题。我将不胜感激任何人都可以阐明这一点!
我正在为父/子组件使用 React hook。
现在我的父组件(companyIcon)中有状态,我需要根据子组件中的一些验证来更新它。我将 validCallback 作为回调函数传递给子组件,并根据从子组件获得的值更新父状态。
现在的问题是在我更新父状态后,子组件中的状态值被重置。我在下面的实现中做错了什么?
function ParentComp(props) {
const [companyIcon, setCompanyIcon] = useState({ name: "icon", value: '' });
const validationCallback = useCallback((tabId, hasError) => {
if (hasError) {
setCompanyIcon(prevItem => ({ ...prevItem, value: 'error'}));
// AFTER ABOVE LINE IS EXECUTED, my Child component state "myAddress" is lost i.e. it seems to reset back to empty value.
}
}, []);
const MyChildCmp = (props) => {
const [myAddress, setmyAddress] = useState('');
useEffect(() => {
if (myAddressExceptions.length > 0) { …Run Code Online (Sandbox Code Playgroud) 这是我的代码
import { useEffect } from "react";
import { Link } from "react-router-dom";
export const PageOne = () => {
useEffect(() => {
return () => {console.log("PageOne")}
}, []);
return (
<>
<h1>PageOne</h1>
<Link to="/two">Page two</Link>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
这是我访问 PageOne 时在控制台中看到的内容
PageOne
Run Code Online (Sandbox Code Playgroud)
这是当我从 PageOne 导航到 PageTwo 时在控制台中打印的内容(PageOne 和 PageTwo 具有相同的结构)
PageOne
PageTwo
Run Code Online (Sandbox Code Playgroud)
所以我认为 useEffect 中定义的返回函数在组件安装和卸载时运行。我在这个项目中使用了react-router-dom和Vite。
这是正常的吗?并且,是否存在一种仅在组件被卸载时才运行副作用函数的方法?
抱歉,如果我犯了一些错误。我是一名新开发人员,也是一名英语学生。
我收到错误消息“无法读取未定义的属性'map'”,但无法弄清原因-地图未起作用,因为“电影”未定义。你能看到我做错了吗?非常感谢。
const Dashboard = () => {
const discoverUrl = 'https://movied.herokuapp.com/discover';
const [movieList, setMovies] = useState({ movies: [] });
useEffect(() => {
const getAllMovies = () => {
fetch(discoverUrl)
.then(response => response.json())
.then(data => setMovies(data))
}
getAllMovies()
}, [])
return (
<ul>
{movieList.movies.map(movie => (
<li>
<p>{movie}</p>
</li>
))}
</ul>
);
}
export default Dashboard```
TypeError: Cannot read property 'map' of undefined
Run Code Online (Sandbox Code Playgroud) 我想知道在使用 React 钩子时清除超时/间隔的正确方法和最佳实践是什么。例如,我有以下代码:
import React, { useState, useEffect, useRef } from 'react';
const Test = () => {
const id = useRef(null)
const [count, setCount] = useState(5)
const [timesClicked, setTimesClicked] = useState(0)
if (!count) {
clearInterval(id.current)
}
useEffect(() => {
id.current = setInterval(() => {
setCount(count => count -1)
}, 1000)
return () => {
clearInterval(id.current)
}
}, [])
const onClick = () => setTimesClicked(timesClicked => timesClicked + 1)
return (
<div>countdown: {count >= 0 ? count : 0}
<hr …Run Code Online (Sandbox Code Playgroud) 我试图了解两者之间的区别:
React.useEffect(() => {
let timerId = Js.Global.setInterval(() => tick(), 1000);
Some(() => Js.Global.clearInterval(timerId));
});
React.useEffect0(() => {
let timerId = Js.Global.setInterval(() => tick(), 1000);
Some(() => Js.Global.clearInterval(timerId));
});
Run Code Online (Sandbox Code Playgroud)
它们都具有相同的类型签名并且都编译但useEffect0什么都不做:
// useEffect0 : unit => option(unit => unit) => unit
// useEffect : unit => option(unit => unit) => unit
Run Code Online (Sandbox Code Playgroud)
要使用https://reasonml.github.io/reason-react/blog/2019/04/10/react-hooks 上的示例,它使用useEffect但如果您更改它使用useState而不是useReducer您必须更改useEffect为useEffect0
原始版本使用useEffect0:
type action =
| Tick;
type state = {
count: int,
}; …Run Code Online (Sandbox Code Playgroud) 我无法满足所有条件:
useCallback,因为我将它设置为子组件的道具(用于防止重新渲染)debounce,因为我的函数是“终点”,可以调用 ~100 次/秒我对最后一点有问题,我在去抖动(1000 毫秒)后的值已过时。
如何使用useCallback+获取当前值debounce?(警报中的值必须与页面相同)
//ES6 const, let
//ES6 Destructuring
const { Component, useCallback, useState, useEffect } = React;
const SUBChildComponent = (props) => (<button onClick={props.getVal}>GetValue with debounce</button>);
const ChildComponent = () => {
// some unstable states
const [someVal1, setSomeVal1] = useState(0);
const [someVal2, setSomeVal2] = useState(0);
const [someVal3, setSomeVal3] = useState(0);
// some callback witch works with states AND called from subClild components
const getVal = …Run Code Online (Sandbox Code Playgroud)由于一个新问题,重新发布了一个与我上次类似的问题。我正在尝试使用带有钩子的上下文来管理我的 React 应用程序中的身份验证。我收到错误TypeError: Cannot destructure property 'isAuthenticated' of 'Object(...)(...)' as it is undefined.,但是当我console.log定义它的属性时,我看false不到undefined。
我有上下文定义和提供者 authContext.js
import React, { useState, useEffect, createContext } from "react";
import axios from "axios";
const AuthContext = createContext();
export { AuthContext };
const AuthContextProvider = (props) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const setAuth = (boolean) => {
setIsAuthenticated(boolean);
};
const apiOptions = {
url: "users/is-verified",
method: "GET",
headers: {
token: localStorage.token,
},
};
function isAuth() { …Run Code Online (Sandbox Code Playgroud) use-effect ×10
reactjs ×9
react-hooks ×6
javascript ×4
use-state ×3
setinterval ×2
api ×1
reason ×1
reason-react ×1
settimeout ×1
usecallback ×1