我有如下的父组件。这里我想在子组件里面设置setLoading函数 加载中。
const ReportRechargeDetail = React.memo(() => {
const [selectedDates, setSelectedDates] = useState([]);
const [loading, setLoading] = useState(false);
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Row className="header-wrapper">
<div>
Select date range to proceed : <Space />
<RangePicker
format="YYYY-MM-DD"
onChange={onChange}
disabled={loading}
onOpenChange={onOpenChange}
disabledDate={(currentDate) => currentDate.isAfter(moment())}
/>
</div>
</Row>
{ selectedDates ? (
<Row className="header-wrapper">
<div>
<PrimeButton
buttonName={"Download report"}
onClick={onClickHeaderButton}
/>
</div>
</Row>
) : (<div></div>)
}
<Tabs defaultActiveKey="1" onChange={callback} type="card">
<TabPane tab="IN APP" key="1">
<GenerateReport
columns={columns}
reportType={"recharge-info/in-app"}
reportName={"Recharge Details "}
breadcrumbName={"RECHARGED_DETAILED_REPORT"}
fileDownloadUrl={""}
selectedDateRange={selectedDates}
isOpen={isOpen}
isLoadingCallBack={setLoading}
/>
</TabPane>
<TabPane tab="BALANCE" key="2">
<GenerateReport
columns={columns}
reportType={"recharge-info/online"}
reportName={"Recharge Details "}
breadcrumbName={"RECHARGED_DETAILED_REPORT"}
fileDownloadUrl={"Recharge"}
selectedDateRange={selectedDates}
isOpen={isOpen}
/>
</TabPane>
</Tabs>
</>
);
});
export default ReportRechargeDetail;
子组件如下。但我收到一个错误,错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:
const GenerateReport = React.memo(
({
columns,
reportType,
reportName,
breadcrumbName,
fileDownloadUrl,
downloadReport,
downloadReportName,
selectedDateRange,
isOpen,
isLoadingCallBack
}) => {
const [show, setShow] = useState(false);
//const [isOpen, setIsOpen] = useState(false);
const [pageNumber, setPageNumber] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [selectedDates, setSelectedDates] = useState(selectedDateRange);
const [performedActionList, setPerformedActionList] = useState([]);
const [totalCount, SetTotalCount] = useState(0);
const [loading, setLoading] = useState(false);
const [requiredTotal, setRequiredTotal] = useState(true);
const dispatch = useDispatch();
const getRecurrentData = (dateStrings) => {
isLoadingCallBack(true);
setLoading(true);
setShow(true);
});
};
return (
<>
{show ? (
<Spin spinning={loading}>
<ViewBoxBody
loading={loading}
showPrimaryButton={false}
columns={columns}
filterSearchBar={false}
dataSource={performedActionList}
onPaginationClick={onPaginationClick}
currentPage={pageNumber}
totalDataCount={totalCount}
pageSize={pageSize}
showSizeChanger={true}
onShowSizeChange={(curent, size) => setPageSize(size)}
hideOnSinglePage={false}
showTotal={(total) => {
return `Total ${total} items`;
}}
/>
<ViewBoxFooter
onPaginationClick={onPaginationClick}
currentPage={pageNumber}
totalDataCount={totalCount}
pageSize={pageSize}
showSizeChanger={true}
onShowSizeChange={(curent, size) => setPageSize(size)}
hideOnSinglePage={false}
showTotal={(total) => {
return `Total ${total} items`;
}}
/>
</Spin>
) : (
<div></div>
)}
</>
);
}
);
答案 0 :(得分:0)
不要将 setLoading
传递给子组件,而是将钩子调用包装在父组件中用户定义的方法中。
...
const toggleLoading = (value) => {
setLoading(value)
}
...
return ...
并在子组件的 props isLoadingCallBack={toggleLoading}
中使用该方法。根据复杂性,将父状态包装在 Context [1] 中是有意义的,以便您可以访问子树中任何位置的值/设置器。
答案 1 :(得分:0)
此错误有错误描述中列出的 3 个原因
<块引用>您的 React 和渲染器版本可能不匹配(例如 React DOM)
你可能违反了钩子规则
您可能在同一个应用中拥有多个 React 副本
让我们先拿数字 2 来确保我们遵循钩子的规则
您的代码看起来不错,但让我们使用一小段工作代码,我们确信可以在您的环境中试用它https://codesandbox.io/s/little-monad-0jo71?file=/src/App.js 试试这里的示例,如果有效,请将其放在单独的页面/路由中那么问题就出在您的代码上,我们将对其进行更多调查。
现在排名第一
<块引用>您的 React 和渲染器版本可能不匹配(例如 反应DOM)
建议的解决方案:
仔细检查你的 react 和 react-dom 版本
现在排名第三
<块引用>您可能在同一个应用中拥有多个 React 副本
建议的解决方案: