【问题标题】:React listen to 1st state change only反应只听第一个状态变化
【发布时间】:2021-03-22 08:26:12
【问题描述】:

我正在使用 useEffect 来响应收听 redux(easy-peasy) 状态变化,但我只想收听第一个值的变化。
因为当我的页面加载时,状态具有默认值,然后进行 API 调用,因此数据发生更改,但 API 是轮询 API,因此它会在短时间内一次又一次地获取数据。但我的要求之一是只收听第一个 API 数据。

这是我尝试过的:

具有空依赖项的第一种方法

useEffect(() => {
        // my code 
    },[])

在这种情况下,我得到的是我的状态的默认值,而不是第一个 API 响应。

依赖项中具有 state 属性的第二种方法

useEffect(() => {
        // my code
    },[myState])

在这种情况下,我不断从 API 获得更新的响应

这两种方法都不适合我。所以请提出一个更好的解决方案。

【问题讨论】:

  • 如果您对响应不感兴趣,为什么还要继续轮询 API?
  • 无论如何,您可以添加一个状态变量来跟踪您是否应该在 useEffect 中运行代码
  • 如果您不需要响应,则不应触发 API 调用。如果不需要,效果不应该运行。因此,您可能可以优化设置状态和效果的方式以防止这种情况发生。但是现在一个肮脏的修复方法是只使用一个 ref 并存储它是否已经更新过一次。然后如果是这样,在你的效果的顶部,你只需检查那个 ref 如果它已经运行,简单的return

标签: javascript reactjs redux easy-peasy


【解决方案1】:

您可以使用 ref 变量并将状态与初始状态(根据您的实现可能是 null、未定义、空对象)进行比较:

const hasRun = useRef(false)

useEffect(() => {
  if (!hasRun.current && myState !== initialState) {
    hasRun.current = true
    // run my code
  }
},[myState])

引用变量不会参与重新渲染。

【讨论】:

    【解决方案2】:

    我通常对此做的是有一个“以前的”状态。

    你可以使用这个钩子来做那个:

    const usePrevious(value) {
      const ref = useRef();
    
      useEffect(() => {
        ref.current = value;
      }, [value]); // only re-run if value changes
    
      // return previous value (happens before update in useEffect)
      return ref.current;
    }
    

    你可以这样做:

    
    // I usually create a distinct initial state
    const [var, setVar] = useState(null);
    const prevVar = usePrevious(var);
    
    useEffect(() => {
      if (var !== prevVar && var !== null) {
        // logic here
      }
    }, [prevVar, var]);
    
    

    您可以通过不使用 usePrevious 挂钩来简化此操作,但该挂钩非常方便,可用于检查前一个值和当前值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-10
      • 2021-07-13
      • 2022-07-27
      • 1970-01-01
      • 2022-01-19
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多