Javascript : 当 setState inside promise 时,得到一个无休止的输出循环

Javascript : When setState inside promise, getting an unending loop of output

我正在尝试使用 javascript API 从 Airtable 加载数据。但是当我尝试在 promise 块中设置数据状态时,promise 不会 'end'.

Airtable API 内容:

export const listRecords = function() {
  const Airtable = require('airtable');
  const base = new Airtable({ apiKey: apiKey }).base(baseId);

  const list = base(tableName)
  .select({ view: 'Grid view' }).all().then(records => {
    return records;
  }).catch(err => {
    if (err) {
        console.error(err);
        return null;
    }
  });

  return list;
};

设置状态内容:

const [state, setState] = useState({
    records: []
});

Promise.all([listRecords()]).then((v) => {
    setState((s) => ({ ...s, records: v }));
});

然后当我在 promise 语句之前、内部或之后放置 console.log 时,它们会在无休止的循环中被调用。所以我的问题是,我该怎么做才能让承诺只有 called/done 一次?

在您的示例中,看起来您在调用 promise 时并未使用 useEffect。任何 API 调用和状态更新都应该在 useEffect 中调用。否则,将有无限次更新,因为 setState 重新渲染组件并再次调用 promise,一遍又一遍。

如果你只想让你的 Promise 运行 挂载,请将其放在具有空依赖项的效果中 Array:

function YourComponent(props) {
  const [state, setState] = useState({
    records: []
  });

  useEffect(() => {
    Promise.all([listRecords()]).then((v) => {
      setState((s) => ({ ...s, records: v }));
    });
  }, []);
}

[] 表示效果只会 运行 一次,在初始安装时。如果您希望 listRecords() 在其他值更改时被调用,请将这些值放在数组中:

function YourComponent({ id }) {
  const [state, setState] = useState({
    records: []
  });

  useEffect(() => {
    Promise.all([listRecords(id)]).then((v) => {
      setState((s) => ({ ...s, records: v }));
    });
  }, [id]);
}