反应useEffect但在设置状态值之后,仅一次

时间:2019-07-17 17:36:29

标签: reactjs

我正在尝试将一些旧的componentDidMount代码迁移到新的useEffect钩子上,并且在弄清楚如何模拟setState的回调行为时遇到问题

我有一系列从api中提取的东西,我只需要在状态和加载后调用一个函数,然后才调用一次

先前的代码:

ComponentDidMount() {
  const response = await getMyArrayFromAPI
  this.setState({ myArray }, () => { initializeArray() })
}

当前代码:

const [myArray, setMyArray] = useState([])

useEffect(() = {
  const response = await getMyArrayFromAPI
  setMyArray(response)
}, [])

useEffect(() => {
  // one time initialization of data

  // initially gets called before myArray has value, when it should be after
  // gets called every time myArray changes, instead of only once

}, [myArray])

3 个答案:

答案 0 :(得分:0)

您可以在第一个myArray函数中设置useEffect,但如果要使用单独的函数,则只需检查其是否为空

useEffect(() => {
  if (!myArray.length) {
    // one time initialization
  }
}, [myArray])

答案 1 :(得分:0)

您可以使用状态来驱动initializeArray是否需要运行,例如

const [array, setArray] = useState(null);
useEffect(() => {
  getMyArrayFromAPI.then(data => setArray(data || []));
}, []);
if (array) {
  // this will only ever run once as we don't set `array` 
  // anywhere other than `useEffect`
  initializeArray();
}

根据initializeArray的实际操作,您可以从then内部运行它,但这完全取决于您。

答案 2 :(得分:0)

我想您可以创建一个自定义setState挂钩来管理您的回调

const useMyCustomStateHook = (initState, cb) => {
 const [customState, updateCustomState] = useState(initState);

 useEffect(() => cb(customState), [customState, cb]);

 return [customState, updateCustomState];
};

这样您就可以拥有

import React, {useState,useEffect} = from 'react'
const [myArray, setMyArray] = useMyCustomStateHook([], initializeArray)

useEffect(() = {
  const response = await getMyArrayFromAPI
  setMyArray(response)
}, [])