I keep running into this React error while working on my Airtable block:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I’m building a filter system that uses a select dropdown to update records in real time. The component has useState for managing the selected value and useEffect for database updates. Both hooks are placed correctly inside my React component, so I can’t figure out what’s wrong. Could this be related to version mismatches between React libraries?
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import {
Select,
initializeBlock,
useBase,
useRecords,
FormField,
Box,
} from '@airtable/blocks/ui';
const database = useBase();
const dataTable = database.getTable("Project Tasks");
export default function TaskFilter() {
let taskRecords = useRecords(dataTable);
var projectIds = [];
const [selectedId, setSelectedId] = useState("");
const query = dataTable.selectRecords({ fields: ["Project ID"] });
taskRecords.forEach(function (record) {
if (projectIds.indexOf(record.getCellValueAsString("Project ID"), -1)) {
projectIds.push({
value: record.getCellValueAsString("Project ID"),
label: record.getCellValueAsString("Project ID")
});
}
});
query.unloadData();
let recordUpdates = [];
useEffect(() => {
const updateRecords = async () => {
taskRecords.forEach(function (record) {
if (record.getCellValueAsString('Project ID') == selectedId) {
recordUpdates.push({
id: record.id,
fields: { 'Is Active': true }
});
}
else if (record.getCellValueAsString('Project ID') !== selectedId &&
record.getCellValueAsString('Is Active') == 'checked') {
recordUpdates.push({
id: record.id,
fields: { 'Is Active': false }
});
}
});
while (recordUpdates.length) {
await dataTable.updateRecordsAsync(recordUpdates.splice(0, 50));
}
}
updateRecords().catch(console.error);
}, [selectedId])
return (
<div>
<FormField label="Select Project">
<Select
options={projectIds}
value={selectedId}
onChange={newId => setSelectedId(newId.toString())}
width="300px"
/>
</FormField>
</div>
);
}