javascript - TypeError:无法通过 useEffect 和 Tabulator 读取未定义的属性“”
问题描述
这是问题的代码框。
该示例包含三个部分:
- 反应功能组件。
- Vanilla JS 网格库。
- useEffect 将它们结合起来。
一个 useEffect 实例化网格,而另一个则监听状态变化以更新网格。
一切正常,直到在网格库中单击一行。
我得到这个错误。
TypeError: Cannot read property 'companyName' of undefined
471 | id={"input-companyName"}
472 | list={"options-companyName"}
473 | className={"form-input"}
> 474 | value={formJournalItems.companyName}
475 | onChange={handleDatalistChange}
476 | onKeyUp={handleKeyUp}
477 | ref={refCompanyName}
325 |
326 | function handleTableRowClick(journalItemId) {
327 | let journalItem = journalItems.filter(item => item.id === journalItemId)[0]
> 328 | setFormJournalItems(journalItem)
329 | }
330 |
331 | function isValidFormInputs() {
这是有问题的代码,其余的可以在codeandbox中看到。
let refCompanyName = React.createRef();
let refTable = useRef(null);
let table = useRef(null);
const [journalItems, setJournalItems] = useState([]);
const initialFormJournalItems = {
id: "",
journalId: "",
companyId: "",
companyName: "",
documentKey: "",
documentDate: "",
debitAccountId: "",
debitAccount: "",
debit: "",
creditAccountId: "",
creditAccount: "",
credit: ""
}
const [formJournalItems, setFormJournalItems] = useState(initialFormJournalItems);
useEffect(() => {
fetch(`http://localhost:4000/journals/${props.match.params.key}/items`)
.then(res => res.json())
.then(data => {
setJournalItems(data)
})
.catch(err => err);
table.current = new Tabulator(refTable.current, {
data: journalItems,
height: "100%",
layout: "fitColumns",
rowClick: function (e, row) {
//e - the click event object
//row - row component
console.log("tabulator journalitems", journalItems) // <------ EMPTY []
console.log(row._row.data)
handleTableRowClick(row._row.data.id)
},
columns: [
{ title: "Компанија", field: "companyName" },
{ title: "Документ", field: "documentKey" },
{ title: "Датум", field: "documentDate" },
{ title: "Должи", field: "debitAccount" },
{ title: "Износ", field: "debit" },
{ title: "Побарува", field: "creditAccount" },
{ title: "Износ", field: "credit" },
],
});
}, []);
// Updates the tabulator table on item change
useEffect(() => {
console.log("useEffect journalItems", journalItems) // <------ POPULATED
console.log("useEffect refTable", refTable)
console.log("useEffect table", table)
table.current.replaceData(journalItems)
}, [journalItems]);
function handleTableRowClick(journalItemId) {
let journalItem = journalItems.filter(item => item.id === journalItemId)[0]
setFormJournalItems(journalItem)
}
return (
<div>
<input
type={"text"}
name={"companyName"}
id={"input-companyName"}
list={"options-companyName"}
className={"form-input"}
value={formJournalItems.companyName}
onChange={handleDatalistChange}
onKeyUp={handleKeyUp}
ref={refCompanyName}
multiple
/>
</div>
)
解决方案
我设法用useRef
函数变量来解决它,并通过将函数定义移动到useEffect
?
const [journalItems, setJournalItems] = useState([]);
let handleTableRowClick = useRef(null);
useEffect(() => {
fetch(`http://localhost:4000/journals/${props.match.params.key}/items`)
.then(res => res.json())
.then(data => {
setJournalItems(data) // Sets the state when the AJAX completes
})
.catch(err => err);
table.current = new Tabulator(refTable.current, {
rowClick: function (e, row) {
console.log("tabulator journalitems", journalItems) // State is lost returns []
handleTableRowClick.current(row._row.data.id)
},
columns: [
{ title: "Компанија", field: "companyName" },
{ title: "Документ", field: "documentKey" },
],
});
}, []);
useEffect(() => {
console.log("useEffect journalItems", journalItems) // Works fine
table.current.replaceData(journalItems) // Uses the new state
handleTableRowClick.current = (journalItemId) => {
console.log("handletablerowclick journalItems", journalItems)
// Find the clicked row from all the rows
let journalItem = journalItems.filter(item => item.id === journalItemId)[0]
setFormJournalItems(journalItem)
}
}, [journalItems]);
推荐阅读
- angular - 2 个 Angular 应用程序的通用 Vendor.bundle.js
- unix - hcitool 开始工作,然后喷出
- java - 如何在文本文件中的单独行中打印数组行
- selenium - 如何通过 VBScript 和 Selenium 根据 html 点击元素
- c# - 发送 HTTPS 获取请求 C# 时出错
- php - 在 laravel 5.6 中使用 eloquent 从表及其数据透视表中获取过滤后的行
- ruby-on-rails - TypeError(SessionsController 类的超类不匹配)
- r - ggplot() 使用 X 和 Y 轴上的日期对数据进行排序 - R
- vba - 在 Word VBA 中创建自定义信息窗口
- mysql - ServiceStack.OrmLite:插入或更新 POCO 中未表示的列?