标签: use-effect

React - 在获取数据并使用该数据设置状态后如何清理 useEffect() ?

我正在使用钩子 useEffect 向我的服务器发出获取请求,并且不断收到此警告:

警告:无法对已卸载的组件执行 React 状态更新。这是一个空操作,但它表明应用程序中存在内存泄漏。要修复此问题,请取消 useEffect 清理函数中的所有订阅和异步任务。

我明白这个警告的原因,但是我该如何清除它呢?我尝试过本文中建议的方法,但没有成功:https://dev.to/pallymore/clean-up-async-requests-in-useeffect-hooks-90h

这是我的代码:

import React, { useEffect, useState } from 'react';
import { Redirect, Route } from 'react-router-dom';

export default function ProtectedRoute({ component: Component, ...rest }) {
    
    const [ user, setUser ] = useState('');

    useEffect(() => {
        const fetchUser = async () => {
            try {
                const response = await fetch('http://localhost:5000/user', {
                    credentials: 'include'
                });

                const data = await response.json();

                setUser(data.session.passport.user);
            
            } catch (error) {
                console.log(error);
            }
        }

        fetchUser();

        return () => …
Run Code Online (Sandbox Code Playgroud)

fetch reactjs react-hooks use-effect

4
推荐指数
1
解决办法
1万
查看次数

简单的 React 文件上传,表单数据不附加

     const [image, setImage] = useState({ preview: "", file: "" });
     const handleChange = (e) => {
        e.preventDefault();
        if (e.target.files.length) {
          setImage({
            preview: URL.createObjectURL(e.target.files[0]),
            file: e.target.files[0],
          });
        }
      };
      useEffect(() => {
        const formData = new FormData();
        formData.append("file", image.file);
        console.log(formData);
      }, [image]);
Run Code Online (Sandbox Code Playgroud)

上面的代码console.log(formData);返回空对象,无法在axios上发送文件

javascript ajax reactjs react-hooks use-effect

4
推荐指数
1
解决办法
7497
查看次数

如果不指定依赖项,useEffect() 有什么意义

useEffect我在功能组件中使用反应钩子,并且想知道当您不指定依赖项时它的用途是什么。我知道文档声明它用于副作用,但我的问题是为什么这些副作用不能在功能组件内使用纯 JS 运行?作为一个非常基本的示例,我正在使用以下代码:

import {useEffect, useState} from 'react'

function Child () {

  const [clickCount, updateCount] = useState(0)

  console.log('Run outside of useEffect')

  useEffect(()=>{
    console.log("Run inside of useEffect")
  })


  return (

    <button onClick = {() => updateCount(clickCount+1)}> Child COmponent </button>
  )
}

export default Child
Run Code Online (Sandbox Code Playgroud)

正如您所期望的那样,它基本上只是一个普通的 JS 函数,在每次由单击按钮引起的重新渲染时,console.log都会执行这两个函数。

我理解为什么您可能想要useEffect在如下情况下使用,您只想useEffect在某些特定更改时运行:

import {useEffect, useState} from 'react'

function Child () {

  const [clickCount, updateCount] = useState(0)

  console.log('Run outside of useEffect')

  //this now only runs when `someVariable` changes
  useEffect(()=>{ …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-hooks use-effect

4
推荐指数
1
解决办法
1280
查看次数

由于 useSelector 更新而导致 useEffect 循环

我有一个 useEffect

function Component () {
    const facets = useSelector(getFacets)

    useEffect(() => {
        dispatch(search(facets, param2, param3))
    }, [dispatch, facets, param2, param3])
    
    //rest of component with return
}
Run Code Online (Sandbox Code Playgroud)

现在搜索实际上会更新facets

//Inside my slice
const search = (facets, param2, param3) => async(dispatch) => {
   //do a fetch using param2 and param3
   //fetch comes back with a facets object
   //alter response facets object based on 'old' facets
   dispatch(setFacets(newFacets)) // set the new facets
}
Run Code Online (Sandbox Code Playgroud)

问题是,当此 useEffect 运行时,重新渲染会导致const facets = useSelector(getFacets)加载新值... Linting …

reactjs redux react-hooks use-effect

4
推荐指数
1
解决办法
4103
查看次数

React 组件状态在组件卸载之前被擦除

如果我返回一个函数,useEffect我可以确定该函数将在组件卸载时运行。但 React 似乎在调用我的卸载函数之前擦除了本地状态。

考虑一下:

function Component () {

  const [setting, setSetting] = useState(false)

  useEffect(() => {

    setSetting(true)

    // This should be called when unmounting component
    return () => {

      console.log('Send setting to server before component is unmounted')
      console.log(setting) // false (expecting setting to be true)
      
    }
  }, [])
  
  return (
    <p>Setting is: {setting ? 'true' : 'false'}</p>
  )
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以确认预期的行为是应该擦除组件状态吗?而且,如果这是正确的行为,那么如何在卸载组件之前将当前组件状态发送到服务器?

为了提供一些上下文,我正在消除对服务器的发布请求,以避免每次用户更改设置时都会触发它。去抖动效果很好,但我需要一种在用户离开页面后触发请求的方法,因为排队的去抖动方法将不再从未安装的组件中触发。

debouncing reactjs use-effect use-state react-component-unmount

4
推荐指数
1
解决办法
1607
查看次数

React Hooks - 更新父组件而不触发无限循环

假设我有一个父组件,它呈现一个子组件,而子组件所做的就是保持某种状态,并在其自身状态发生变化时触发 onChange 处理程序。请参阅下面的代码或 CodeSandbox。

代码沙盒示例

这段代码进入无限循环,我想摆脱这种行为。

可能的解决方案,但我不喜欢的解决方案:

1:我可以将所有状态放在父组件中,并用父组件控制子组件,但这并不是我真正想要的。在现实生活中,我的子组件不仅仅负责一个简单的计数器,而且我想从父组件中轻松使用它。子组件内部有复杂的行为,我想向父组件传达一些简单的更改。或者这在 React 中是绝对不能做的吗?(保持子级状态并触发父级状态更新的更改)我想说这不一定吗?

2:我还可以从handleInternalChange 处理程序中触发onChange 处理程序。而且,也不是我想要的。在现实生活中,我的子组件将从组件本身的几个不同位置进行更新,因此状态更改是观察和触发 onChange 父组件的最优雅的方式。

3:我可以省略 useEffect 依赖项数组中的 onChange 依赖项。不推荐这样做,React社区参考了这个解释。我理解,只是我觉得这种情况是例外?** 另外,我使用 CRA,它带有开箱即用的很棒的 linter 等,如果我从依赖项中删除 onChange 处理程序,linter 会抱怨它,而且我不喜欢开始制定自己的班轮规则。对于像我这样的简单用例,社区设置的 linter 应该可以正常工作。

我认为会发生什么认为会发生的是,父级被更新,然后重新渲染整个事物,并且不知何故, onChange 处理程序也被“更改”。据我所说,该函数实际上并没有改变,但 React 认为(或知道)它改变了,因此它在子组件中再次触发 useEffect 调用,然后无限循环诞生。

但是,就我而言, onChange 函数没有改变。那么为什么会触发 useEffect 调用呢?我怎样才能防止这种情况发生?

import React, { useState, useEffect } from "react";

const Comp = ({ onChange }) => {
  const [internalState, setInternalState] = useState(0);
  const handleChange = () => {
    setInternalState(internalState + 1);
  };

  useEffect(() => { …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-hooks use-effect

4
推荐指数
1
解决办法
2940
查看次数

反应按键事件仅采用初始状态值而不是更新值

我正在创建一个 React 应用程序,其中有一种称为输入的状态,它正在从用户那里获取输入。我希望当我按下回车键时,警报应该显示正在设置状态的输入。但是,单击enter按键时,仅显示输入状态中设置的默认值。

但是,当我单击按钮(我创建该按钮是为了在警报中显示输入)时,警报中显示的输入是正确的。

请参阅下面的代码片段以供参考:

import React, { useEffect, useRef, useState } from 'react';

export default function ShowAlertExample() {

  const [input, setInput ] = useState('1');
  const handleInputChange = (e) => {
    setInput(e.target.value);
  }

  const handleShowAlert = () => {
    alert(input);
  }

  const checkKeyPress = (e) =>{
    const { key, keyCode } = e;
    console.log(key, keyCode)
    if (keyCode === 13 ) {
      alert(input);
    }
  }

  useEffect(()=>{
    window.addEventListener("keydown", checkKeyPress)
    return ()=>{
      window.removeEventListener("keydown", checkKeyPress)
    }
  }, [])
  
  return (
    <div>
      <header …
Run Code Online (Sandbox Code Playgroud)

javascript dom-events reactjs use-effect use-state

4
推荐指数
1
解决办法
9214
查看次数

React useEffect 调用 API 的次数过多,如何在组件渲染时将 API 调用限制为仅一次?

我在 useEffect 挂钩中调用 get API,以在组件安装之前获取数据,但它多次调用 API,并且收到错误“To many API requests”。

const [total, setTotal] = useState(0);
const [message, setMessage] = useState('');

useEffect(() => {
    covidApi.getData({url:'/totals'})
    .then((response) => {
        setTotal(response.data[0]);
        setMessage('');
        console.log(response.data);
    })
    .catch((error) => {
        setMessage("No data found");
        console.log(error);
    })
});
Run Code Online (Sandbox Code Playgroud)

输出:

浏览器输出

请让我知道这是在使用 useEffect 钩子渲染组件之前从 API 获取数据的最佳方式。

reactjs react-hooks use-effect

4
推荐指数
1
解决办法
6953
查看次数

如何从 UseEffect Hook 返回值

我从 Use Effect 挂钩(我对此相对较新)获取纬度和经度。我想返回使用效果挂钩之外的值,并将它们存储在变量中,甚至在需要时存储在状态中。我可以控制台记录值,但我是否只添加返回语句或以某种方式传递参数?我需要使用什么功能?我计划将纬度和经度数据传递到代码的其他部分,这就是为什么我尝试从 useEffect 挂钩检索它。

useEffect(() => {
    if ("geolocation" in navigator) {
      console.log("Available");
    } else {
      console.log("Not Available");
    }
    navigator.geolocation.getCurrentPosition(function (position) {
      let lat = position.coords.latitude;
      let long = position.coords.longitude;
      console.log(lat);
      console.log(long);
    });
  }, []);
Run Code Online (Sandbox Code Playgroud)
let newLat = lat?
let newLong = long?
Run Code Online (Sandbox Code Playgroud)

arguments parameter-passing reactjs use-effect

4
推荐指数
1
解决办法
9785
查看次数

如何在另一个自定义 Hook 中使用返回值的自定义 Hook?

我正在使用 React-native,其中有一个名为的自定义 Hook,它使用useUser该方法从 AWS Amplify 获取用户信息Auth.getUserInfro,然后获取返回对象的一部分并用它设置一个状态变量。我还有另一个名为 hook 的useDataHook,它根据 userId 获取一些数据并将其设置为状态变量。

使用用户自定义挂钩:

import React, { useState, useEffect } from "react";
import { Auth } from "aws-amplify";

const getUserInfo = async () => {
  try {
    const userInfo = await Auth.currentUserInfo();
    const userId = userInfo?.attributes?.sub;
    return userId;
  } catch (e) {
    console.log("Failed to get the  AuthUserId", e);
  }
};

const useUserId = () => {
  const [id, setId] = useState("");

  useEffect(() => {
    getUserInfo().then((userId) => { …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-native react-hooks use-effect

4
推荐指数
1
解决办法
1万
查看次数