因此,当使用useEffect调用依赖于状态的函数时,我有以下情况。
例子:
// INSIDE APP COMPONENT
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
function someFunction() {
return someState + 1;
}
React.useEffect(() => {
const newState = someFunction(); // 'someFunction' IS BEING CALLED HERE
setSomeState(newState);
},[someTrigger])
Run Code Online (Sandbox Code Playgroud)
问题:
在这种情况下,我应该someFunction在内部声明useEffect()还是将其保存在外部(但在组件主体内部)是否安全?
我可以将它添加到dependency数组中,但它会损害我的代码的可红性,因为我想专注于trigger.
由于useEffect()将在新渲染后运行,假设它将拥有我在其中调用的函数的新副本是否安全?
关于何时应该在useEffect钩子内声明函数或何时必须将其添加到依赖项数组中,是否有基本规则?
编辑:请注意,useEffect有这些函数的新副本是必要的,因为这些函数需要访问一些新的最新state变量。
笔记:
此代码在CodeSandbox上触发以下eslint 警告。虽然它工作得很好。
React Hook React.useEffect 缺少一个依赖项:'someFunction'。包括它或删除依赖项数组。(react-hooks/exhaustive-deps)eslint
真实案例:
这是一个简化的例子。在我的真实案例中,这是一个带有过滤器组件的产品搜索页面。所以当我点击一个过滤器来激活它(比如说,price <= …
我有一个从数据库中提取的对象列表(在我的例子中是“专辑”)。我需要编辑这些对象。在 useEffect 挂钩中的编辑组件中,我启动了使用其 ID 获取所需专辑的操作。这个动作有效。但是,在同一个 useEffect 中,我试图在触发操作之前获取更改的 redux 状态。现在我面临这个问题——我获取的只是 previos 状态。如何在当前 redux 状态的 useEffect 获取中实现?
我在这里看到过类似的问题,但是没有一个答案对我的用例有帮助。
我正在使用 redux-thunk。
编辑组件。问题出现在 setFormData 中 - 它从减速器中获取以前的状态,而不是当前的状态。它似乎在状态被 getAlbumById 改变之前触发:
//imports
const EditAlbum = ({
album: { album, loading},
createAlbum,
getAlbumById,
history,
match
}) => {
const [formData, setFormData] = useState({
albumID: null,
albumName: ''
});
useEffect(() => {
getAlbumById(match.params.id);
setFormData({
albumID: loading || !album.albumID ? '' : album.albumID,
albumName: loading || !album.albumName ? '' : album.albumName
});
}, [getAlbumById, loading]);
const { albumName, albumID …Run Code Online (Sandbox Code Playgroud) 在 useEffect 的依赖数组中定义 setState 值背后的想法是什么:
const [someState, setSomeState] = useState();
...
useEffect(() => {
// Do something
setSomeState('some value');
}, [setSomeState]);
Run Code Online (Sandbox Code Playgroud)
React Hook useEffect has a missing dependency: 'setSomeState'.
Either include it or remove the dependency array.
eslint(react-hooks/exhaustive-deps)
Run Code Online (Sandbox Code Playgroud)
不确定这个例子是否会导致 eslint 要求setSomeState在依赖数组中定义,但我在使用 useEffect 编写时看到了这种时刻。在这种情况下,React 在听什么?我的理解是useEffect监听依赖数组中值的变化,但会setSomeState发生变化吗?我在这里缺少什么?
我想在第一次触发时运行一个延迟的间隔。我该如何使用 useEffect 来做到这一点?由于语法,我发现很难实现我想做的事情
区间函数
useEffect(()=>{
const timer = setInterval(() => {
//do something here
return ()=> clearInterval(timer)
}, 1000);
},[/*dependency*/])
Run Code Online (Sandbox Code Playgroud)
延迟功能
useEffect(() => {
setTimeout(() => {
//I want to run the interval here, but it will only run once
//because of no dependencies. If i populate the dependencies,
//setTimeout will run more than once.
}, Math.random() * 1000);
}, []);
Run Code Online (Sandbox Code Playgroud)
当然,它是可以以某种方式实现的......
考虑以下示例:
const userRole = sessionStorage.getItem('role');
const { data, setData, type, setTableType } = useTable([]);
useEffect(() => {
const getData = async () => {
// fetch some data from API
const fetchedData = await axios('..');
if (userRole === 'admin') {
setData([...fetchedData, { orders: [] }]);
} else {
setData(fetchedData);
}
if (type === '1') {
setTableType('normal');
}
};
getData();
}, []);
Run Code Online (Sandbox Code Playgroud)
我只想在安装时运行此效果,仅此而已,我不在乎userRole或是否setData已更改!
所以,现在我的问题是:
userRole在依赖项数组中丢失?它甚至不是一个国家!setData在依赖项数组中缺少它是不是它总是相同的引用或者它是否会改变?这很可能是一个愚蠢的问题——我的理解是,任何引发副作用的事情都应该用 来处理useEffect。我想知道这种理解是否正确。特别是在进行 API 调用的情况下——在钩子中进行 API 调用好吗useCallback?
我想知道使用(或不使用)useEffect 更新 useLocation 之间的最大区别是什么。
我通常发现人们在 useEffect 中设置 useLocation 来在 URL 路径发生变化时更新状态,但我发现我不需要这样做来更新位置。
const NavBar = () => {
const location = useLocation();
const [currentPath, setCurrentPath] = useState('')
const location = useLocation();
console.log('pathname:', location.pathname)
useEffect(() => {
setCurrentPath(location.pathname);
}, [location]);
console.log('currentPath:', currentPath)
...
}
Run Code Online (Sandbox Code Playgroud)
Returns
pathname: /results:Cancer
currentPath: /results:Cancer
Run Code Online (Sandbox Code Playgroud)
我的意思是,我发现的唯一区别是,使用 useEffect 时,返回将在组件安装后发生。我正在尝试了解成为更好的程序员的最佳实践。
useEffect我正在从hook进行 api 调用
function ChangePassword(props) {
const token = props.match.params.token;
const [state, setState] = useState({
password: "",
confirmPassword: "",
});
const [status, setStatus] = useState({
loaded: false,
auth: false,
});
useEffect(() => {
let { auth } = status;
axios
.get(
`http://localhost:2606/api/hostler/changepassword?token=${token}`
)
.then((res) => {
console.log("res", res);
auth = res.status === 202;
})
.then(() => setStatus({ auth, loaded: true }))
.catch((err) => console.log("err", err));
},[]);
return (
// code
);
}
Run Code Online (Sandbox Code Playgroud)
但反应发出警告
React Hook useEffect 缺少依赖项:“状态”和“令牌”。包含它们或删除依赖项数组react-hooks/exhaustive-deps
添加status …
我创建了一个应用程序来进行 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) reactjs ×10
use-effect ×10
react-hooks ×6
javascript ×3
dependencies ×1
react-native ×1
react-redux ×1
setinterval ×1
settimeout ×1
side-effects ×1
url ×1
use-state ×1
usecallback ×1