【问题标题】:useEffect is returning undefined even though "then" is returning a value response即使“then”返回值响应,useEffect 也返回未定义
【发布时间】:2020-12-11 08:29:44
【问题描述】:

我似乎无法弄清楚为什么 useEffect 会这样做...... Wait() 是一个睡眠异步函数,getData() 是一个 Axios 请求。

        return wait().then(getData().then((resp) => {
            console.log(resp)
        }))

此代码记录了 resp 变量的有效值,但它在 return 语句中返回 undefined。发生了什么,如何让它返回 resp 变量?

编辑***

const wait = React.useCallback( async() => {
    if (loading === false) {
        await sleep(4000);
    } else if (loading === true){
        await sleep(0);
    } else {
        await sleep(2000);
    }
}, [loading])

const getData = React.useCallback(() => {
    const value = Axios.post("http://localhost:3001/api/get-value",
    {user: userProp}).then((response) => {
        const recievedData = response.data;
        const dataValue = recievedData.map((val) => {
            return [val.value]
        })
            if (loading === true){
                setLoading(false);
            }
        return parseInt(dataValue);
    }).then((resp) => {
        setMoisture(resp) // if I turn this off still no go.
        return resp
    })
    return value
}, [userProp, loading])

const Data = React.useCallback(() => {
    try {
        return wait().then(getData)
    } catch (error) {
        setError(true);
        return error;
        }   
}, [wait, getData])

React.useEffect(() => {
    let isEffect = false
    if (props.location.state !== undefined) {
        Data().then((firstResponse) => {
            if (!isEffect){
                setMoisture(firstResponse)
            }
        })
    }
    return () => {
        isEffect = true;
    }
}, [props.location.state, Data, moisture]);  

【问题讨论】:

  • 您的链接不完全正确,您还需要在最后返回值。尝试这样的事情:return wait().then(getData).then(resp => resp) 虽然如果你在最终的.then 中除了返回值之外没有做任何事情,那么它实际上不是必需的,你可以省略它
  • 谢谢!这解决了我未定义的问题,但我的状态不再更新。
  • 好的,但你是如何尝试更新状态的?添加所有相关代码
  • 好的,我添加了更多代码。如果您还需要什么,请告诉我。

标签: javascript reactjs asynchronous promise use-effect


【解决方案1】:

提供给useEffect的回调必须返回一个函数或未定义(如果提供了一个函数,这被认为是一个清理函数。清理函数用于分离事件监听器,取消任何正在进行的请求,并在组件被卸载时阻止任何更新)

为了访问你的http请求产生的响应,你应该把它存储在一个状态中(你可以使用useState或useReducer)

const [rest, setResp] = React.useState();

React.useEffect(() => {
 wait().then(_ => getData()).then(setResp);
}, [YOUR_DEPENDENCIES]);

// update jsx based on rest

根据您问题中的更新,您需要的是轮询

请查看下面的示例(请记住,这是说明可能解决方案的代码)

function usePolling(fetcher, interval) {
  const [payload, setPayload] = React.useState(null);
  
  React.useEffect(function () {
    // you must implement the error handling
    fetcher()
      .then(function (resp) {
        setPayload(resp)
      })
    
  }, [fetcher]);
  
  React.useEffect(function () {
    let timeoutId;
    
    function poll() {
      timeoutId = setTimeout(function () {
        // you must implement the error handling
        fetcher()
          .then(function (resp) {
            setPayload(resp)
            poll();
          })
      }, interval);
    }
    poll()
    
    return function () {
      clearTimeout(timeoutId);
    }
  }, [fetcher, interval]);
  
  return payload;
}


function App() {
  const payload = usePolling(function () {
    return Promise.resolve(Date.now())
  }, 3000);
  
 
  return (
    <div>polling payload: {payload}</div>
  )
}

ReactDOM.render(<App/>, document.getElementById('app'))
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

【讨论】:

  • 当我这样做时,它会停止更新状态。知道为什么吗?为了澄清我正在使用 axios 从 mysql 获取数据,每 10 秒就有新数据进入它。
  • 我不知道你为什么这么多使用 useCallback(看起来你优化得太早了)
  • 这是因为我不断收到警告告诉我使用它。从字面上看,这是唯一的原因。大声笑
  • 警告可能是针对 useEffect 而不是 useCallback(您应该仔细检查)。我已经更新了我的答案,以说明您的问题可能的解决方案
  • usePolling 会根据给定的区间值调用 fetcher 函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
相关资源
最近更新 更多