I'm trying to load data from Airtable with the javascript API. But when I try to setState of data inside of a promise block, the promise doesn't 'end'.
Airtable API stuff:
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;
};
Setting state stuff:
const [state, setState] = useState({
records: []
});
Promise.all([listRecords()]).then((v) => {
setState((s) => ({ ...s, records: v }));
});
Then when I put console.log before, inside, or after the promise statement, they get called in an unending loop. So my question is, how do I make it so the promise is only called/done once?
If you only want your Promise to run on mount, place this in an effect with an empty dependencies Array:
function YourComponent(props) {
const [state, setState] = useState({
records: []
});
useEffect(() => {
Promise.all([listRecords()]).then((v) => {
setState((s) => ({ ...s, records: v }));
});
}, []);
}
The []
means that the effect will only run once, on initial mount. If you want listRecords()
to be called when other values change, place those values inside of the Array:
function YourComponent({ id }) {
const [state, setState] = useState({
records: []
});
useEffect(() => {
Promise.all([listRecords(id)]).then((v) => {
setState((s) => ({ ...s, records: v }));
});
}, [id]);
}