为什么在useEffect中调用函数时收到反应挂钩警告?

时间:2020-02-04 00:27:44

标签: reactjs

我有这个useEffect,它抱怨添加不在依赖项中。

useEffect(()=>{
    add();
}, [count]);

该应用是我的计数器,但无法正常运行。每当计数器更改时,我都希望添加到我执行的更改历史记录中,如下所示:

const [hist, setHist] = useState({
        past: [],
        present: 0,
        future: []
    }
);

此外,这应该发生

const add = () => {
    const newPresent = count;

    setHist({
        past: [...hist.past, hist.present],
        present: newPresent,
        future: []
    });

    console.log("add count:", count);
    console.log("add hist:", hist);
}

但是在计数器中添加或删除时,尽管在控制台上“添加计数”会记录当前计数状态(假设为-1),但存在:历史上总是向后退一步。还将零添加到过去:两次数组。

当我在依赖项数组中添加“ add”时,出现编译错误

ReferenceError: can't access lexical declaration `add' before initialization

https://codesandbox.io/s/festive-dew-3ix3d

编辑:这是一个撤消/重做的工作示例,其计数器使用了来自SILENT答案的提示:

https://codesandbox.io/s/angry-blackwell-bsdsx

1 个答案:

答案 0 :(得分:2)

所以我不得不改变很多。通常我不这样做,但是似乎很快。这是历史的反击;

import React, { useState, useCallback } from "react";
import Context from "./Context";

const ContextProvider = props => {
  const [hist, setHist] = useState({
    past: [],
    present: 0,
    future: []
  });

  const incr = useCallback(() => {
    setHist(({ past, present }) => {
      past = [...past, present];
      return {
        past,
        present: present + 1
      };
    });
  }, []);

  const decr = useCallback(() => {
    setHist(({ past, present }) => {
      past = [...past, present];
      return {
        past,
        present: present - 1
      };
    });
  }, []);

  const undo = useCallback(() => {
    setHist(hist => {
      let { past, present, future = [] } = hist;
      past = [...past];
      future = [...future, present];
      present = past.pop();
      console.log("undo:", past, present, future);
      return {
        past,
        present,
        future
      };
    });
  }, []);

  const redo = useCallback(() => {
    setHist(hist => {
      let { past, present, future } = hist;
      if (future && future.length > 0) {
        future = [...future];
        past = [...past, present];
        present = future.pop();
        return {
          past,
          present,
          future
        };
      }
      return hist;
    });
  }, []);

  return (
    <Context.Provider
      value={{
        count: hist.present,
        incr,
        decr,
        undo,
        redo
      }}
    >
      {props.children}
    </Context.Provider>
  );
};

export default ContextProvider;

计数器状态重复

import React, { useState, useCallback } from "react";
import Context from "./Context";

const ContextProvider = props => {
  const [count, setCount] = useState(0);
  const [, setHist] = useState({
    past: [],
    present: 0,
    future: []
  });

  const incr = useCallback(() => {
    setHist(({ past, present }) => {
      past = [...past, present];
      let nC = count + 1;
      setCount(nC);
      return {
        past,
        present: nC
      };
    });
  }, [count]);

  const decr = useCallback(() => {
    setHist(({ past, present }) => {
      past = [...past, present];
      let nC = count - 1;
      setCount(nC);
      return {
        past,
        present: nC
      };
    });
  }, [count]);

  const undo = useCallback(() => {
    setHist(hist => {
      let { past, present, future = [] } = hist;
      past = [...past];
      future = [...future, present];
      present = past.pop();
      setCount(present);
      console.log("undo:", past, present, future);
      return {
        past,
        present,
        future
      };
    });
  }, []);

  const redo = useCallback(() => {
    setHist(hist => {
      let { past, present, future } = hist;
      if (future && future.length > 0) {
        future = [...future];
        past = [...past, present];
        present = future.pop();
        setCount(present);
        return {
          past,
          present,
          future
        };
      }
      return hist;
    });
  }, []);

  return (
    <Context.Provider
      value={{
        count,
        incr,
        decr,
        undo,
        redo
      }}
    >
      {props.children}
    </Context.Provider>
  );
};

export default ContextProvider;

https://codesandbox.io/s/heuristic-cherry-oqted