Reputation: 919
I am using react table 7 with subcomponents. I've built my table using the example provided in the React Table 7 API examples. However, I get a warning,
React Hook React.useCallback has missing dependencies: 'props.setStatus' and 'statusColumns'. Either include them or remove the dependency array
The dependencies are stated as variables before the return statement, but within the function. The column names are recognized and implemented correctly, so why am I getting this warning and how can I prevent this?
Here is the code implementation:
const EnforcementActionsTable = (props) => {
const columns = [
{
Header: () => null, // No header
id: "expander", // It needs an ID
width: 30,
Cell: ({ row }) => (
<span {...row.getToggleRowExpandedProps()}>
{row.isExpanded ? (
<FontAwesomeIcon className="font-icon" icon={faCaretDown} />
) : (
<FontAwesomeIcon className="font-icon" icon={faCaretRight} />
)}
</span>
)
},
{
Header: "Edit Action",
id: "eaId",
Cell: (row) => {
return (
<div className="text-center">
<FontAwesomeIcon
className="font-icon"
icon={faEdit}
onClick={() => {
props.handleShow(props.id);
props.setItem(row.original);
}}
/>
</div>
);
},
width: 75,
disableFilters: true
},
{
Header: "Add Status",
id: "eaStatus",
Cell: (row) => {
return (
<div className="text-center">
<FontAwesomeIcon
className="font-icon"
style={{ color: "green" }}
icon={faPlusCircle}
onClick={() => {
props.handleShow(props.statusModalId);
props.setItem(row.original);
}}
/>
</div>
);
},
width: 75,
disableFilters: true
},
{
Header: "EA Code",
accessor: "eaCode",
width: 100
},
{
Header: "Assigned To",
accessor: "assignedTo"
},
{
Header: "Date Intiated",
id: "dateInitiated",
accessor: (d) => {
return d.dateInitiated ? formatDateMDY(d.dateInitiated) : "";
},
width: 135
},
{
Header: "Due Date Req.",
id: "dueDateRequired",
accessor: (d) => {
return d.dueDateRequired ? "Yes" : "No";
},
width: 135
},
{
Header: "Due Date",
id: "dueDate",
accessor: (d) => {
return d.dueDate ? formatDateMDY(d.dueDate) : "";
},
width: 100
},
{
Header: "Date Completed",
id: "dateComplete",
accessor: (d) => {
return d.dateComplete ? formatDateMDY(d.dateComplete) : "";
}
},
{
Header: "Days Past",
id: "daysPassed",
accessor: (d) => {
return d.daysPassed ? <span className={d.daysPassed < 0 ? "error" : ""}>{d.daysPassed}</span> : "";
}
}
];
const statusColumns = [
{
Header: "Edit Status",
id: "eaId",
Cell: (row) => {
return (
<div className="text-center">
<FontAwesomeIcon
className="font-icon"
icon={faEdit}
onClick={() => {
props.handleShow(props.statusModalId);
props.setStatus(row.original);
}}
/>
</div>
);
},
width: 75,
disableFilters: true
},
{
Header: "",
id: "viewComplianceSchedule",
accessor: (d) => {
return d.status === "Compliance" ? (
<span
style={{ textDecoration: "underline", color: "#5fa7be", cursor: "pointer" }}
onClick={() => {
props.handleShow(props.complianceModalId);
props.handleShowComplianceSchedule(d.tenschdIsNumber);
}}
>
<FontAwesomeIcon className="font-icon" icon={faEye} />
</span>
) : (
""
);
},
disableFilters: true,
width: 65
},
{
Header: "Status",
accessor: "status"
},
{
Header: "Initial Date",
id: "dateInitiated",
accessor: (d) => {
return d.dateInitiated ? formatDateMDY(d.dateInitiated) : "";
}
},
{
Header: "Response Required",
id: "responseRequired",
accessor: (d) => {
return d.responseRequired ? "Yes" : "No";
}
},
{
Header: "Response Due",
id: "responseDue",
accessor: (d) => {
return d.responseDue ? (
<span className={d.responseDue < new Date() ? "error" : ""}>{formatDateMDY(d.responseDue)}</span>
) : (
""
);
}
},
{
Header: "Response Received",
id: "responseReceived",
accessor: (d) => {
return d.responseReceived ? formatDateMDY(d.responseReceived) : "";
}
},
{
Header: "Staff Assigned",
accessor: "assignedStaff"
},
{
Header: "Date Completed",
id: "statusComplete",
accessor: (d) => {
return d.statusComplete ? formatDateMDY(d.statusComplete) : "";
}
},
{
Header: "Comments",
accessor: "responseComments",
width: 200
}
];
return (
<React.Fragment>
<Row>
<Col>
<EnforcementStatusModal item={props.item} {...props} />
</Col>
<Col>
<EnforcementActionModal item={props.item} {...props} />
</Col>
</Row>
<Col>
<ComplianceScheduleModal {...props} />
</Col>
<Row>
<Col>
<Table
columns={columns}
data={props.data}
rowOnClick={true}
rowClickHandler={props.setItem}
renderRowSubComponent={React.useCallback(
({ row }) =>
row.original.enforcementActionStatusList.length > 0 ? (
<Table
data={row.original.enforcementActionStatusList}
columns={statusColumns}
rowOnClick={true}
rowClickHandler={props.setStatus}
/>
) : (
"No data"
),
[]
)}
/>
</Col>
</Row>
</React.Fragment>
);
};
export default EnforcementActionsTable;
Upvotes: 0
Views: 968
Reputation: 1190
Add props.setStatus
and statusColumns
to the dependency array.
renderRowSubComponent={React.useCallback(
({ row }) =>
row.original.enforcementActionStatusList.length > 0 ? (
<Table
data={row.original.enforcementActionStatusList}
columns={statusColumns}
rowOnClick={true}
rowClickHandler={props.setStatus}
/>
) : (
"No data"
),
[statusColumns,props.setStatus]
)}
As per the hooks documentation
useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
Upvotes: 1