为什么我的 useEffect 在修改它的依赖项时没有进入无限循环?

Why doesn't my useEffect go into an infinite loop when modifying it's dependency?

代码

PrizeHistory.js

...

const PrizeHistory = () =>  {
  const [history, setHistory] = useState([]);

  useEffect(() => {

    async function getHistory () {
      try {
        let result = await sqliteInterface.getAllPrizes(db, prizeTable);
        result == null ? console.log("res is null") : setHistory(result);
        console.log("result" + result);
        console.log("history" + history);
      } catch (err) {
        console.log(err);
      }
    }

    getHistory();
  }, [history])

  return (
    <View style={styles.body}>
      <Text style={styles.text}>Prize History</Text>
    </View>
  );
}

getAllPrizes

getAllPrizes(db, tableName) {
    return new Promise((resolve, reject) => {
      db.transaction((tx) => {
        tx.executeSql(
          `SELECT * FROM ${tableName};`, 
          [],
          (tx, res) => {
            let len = res.rows.length;
            let results = [];  

            if(len > 0) {
              for(i = 0; i < res.rows.length; i++) {
                results.push(res.rows.item(i));
              }
            } 
            console.log("resolving promise now");
            resolve(JSON.stringify(results));
          },
          (error) => {
            reject(Error(`SQLite getAllPrizes: failed to get '*' from ${tableName}: ` + error));
          }
        );
      }); 
    });
  }

目标

页面挂载时,将历史状态设置为数据库中的数据。我最初试过这个:

  useEffect(() => {

    async function getHistory () {
      try {
        let result = await sqliteInterface.getAllPrizes(db, prizeTable);
        result == null ? console.log("res is null") : setHistory(result);
        console.log("result" + result);
        console.log("history" + history);
      } catch (err) {
        console.log(err);
      }
    }

    getHistory();
  }, [])

但它从未正确设置我的历史变量。我刚得到一个空数组(这是我最初将历史状态设置为的数组)。我希望 history 变量等于 history console.log() 中的结果变量,但事实并非如此。

所以我将 useEffect() 更改为:

  useEffect(() => {

    async function getHistory () {
      try {
        let result = await sqliteInterface.getAllPrizes(db, prizeTable);
        result == null ? console.log("res is null") : setHistory(result);
        console.log("result" + result);
        console.log("history" + history);
      } catch (err) {
        console.log(err);
      }
    }

    getHistory();
  }, [history])

此代码正确更改了历史变量,但我预计它会进入无限循环...但它没有?这是我的逻辑

  1. useEffect()[history] 作为依赖项
  2. onMount,history设置为默认值[]
  3. useEffect() 看到 history 已设置并开始 运行
  4. useEffect() 重置 history
  5. useEffect() 应该 重新开始,因为它重置了 history 变量本身
  6. 无限次重复 3-5...

但它不会无限重复...

我的问题

  1. 为什么当 [history] 被设置为它的依赖时 useEffect() 不是无限地 运行
  2. 为什么 useEffect() 没有在安装时正确设置我的历史变量,因为它具有 [] 作为依赖项。

您第一个问题的答案是:history 在第一次设置后不会改变,因为您的 getAllPrizes returns 始终是相同的值,因此仅触发 useEffect一次(在山上)。

对于第 2 个问题,问题是您试图在调用异步的 setHistory 后立即记录 history 值。如果您想在每次更新时记录 history,您必须执行以下操作:

useEffect(() => {
  console.log(history)
}, [history])

您确定您没有尝试在此行设置字符串类型吗:

result == null ? console.log("res is null") : setHistory(result);

据我所知,初始类型是一个数组,解析函数 returns 是一个字符串化对象。 您在控制台中收到任何警告吗?