我知道这是非常常见的错误Invariant Violation: Hooks can only be called inside the body of a function component
,但我仍然无法弄清楚如何在我的代码中修复它。
我的理解是问题在于useMemo
我的代码中的钩子?请指导我。据我了解,问题是 React 和 ReactDOM 的版本不匹配,或者与我没有正确调用我的钩子有关。父组件使用 react 15,子组件的代码参考 react 16.8 代码。
问题是特定于此代码 -
/**
* Get the difference from parseDiff in a formatLines
*/
const diff = useMemo(() => {
const diffText = formatLines(
diffLines(props.startupConfigData, props.runningConfigData),
{
context: 3
}
);
const [diff] = parseDiff(diffText, { nearbySequences: "zip" });
return diff;
}, [props.startupConfigData, props.runningConfigData]);
const { type, hunks } = diff;
/**
* Token used for useMemo
*/
const tokens = useMemo(() => tokenize(hunks), [hunks]);
我的完整组件代码 -
import React, { useMemo } from "react";
import { diffLines, formatLines } from "./unidiff";
import { parseDiff, Diff, Hunk } from "react-diff-view";
import "./diff.less";
import tokenize from "./tokenize";
import { DnxLoader } from "*external*/@cisco-dna/dnx-react-components";
import i18n from "amdi18n-loader!~/nls/i18_compliance";
import { labels } from "../constants";
import { getStatusComplianceType } from "../common";
const DiffViewer = props => {
const { compareWith } = props;
/**
* Get the difference from parseDiff in a formatLines
*/
const diff = useMemo(() => {
const diffText = formatLines(
diffLines(props.startupConfigData, props.runningConfigData),
{
context: 3
}
);
const [diff] = parseDiff(diffText, { nearbySequences: "zip" });
return diff;
}, [props.startupConfigData, props.runningConfigData]);
const { type, hunks } = diff;
/**
* Token used for useMemo
*/
const tokens = useMemo(() => tokenize(hunks), [hunks]);
/**
* Get text based on selection - startup/running
*/
const getStartupText = () => {
if (compareWith == undefined || compareWith === "startup") {
return i18n.label_startup_configuration;
} else {
return i18n.label_running_configuration;
}
};
/**
* Get date format
* @param {*} date
*/
const getFormattedDate = date => {
var lastUpdateTimeData;
const notAvailable = i18n.label_non_applicable;
if (date !== null) {
lastUpdateTimeData = moment(date).format(labels.lastUpdateTimeFormatAmPm);
} else {
lastUpdateTimeData = notAvailable;
}
return lastUpdateTimeData;
};
const statusDisplayDetails = getStatusComplianceType(
"COMPLIANT",
true
);
/**
* return function
*/
return (
<div className="margin-left-right">
{hunks ? (
<div>
<div className="flex">
<div className="startup-text">
{getStartupText()}
<div className="font-size-10">
{i18n.label_no_of_lines}:{" "}
{props.startUpFile.totalNoOfLines}
</div>
<div className="font-size-10">{i18n.label_archived_on}: {getFormattedDate(props.startUpFile.createdTime )}</div>
</div>
<div className="running-text">
{i18n.label_running_configuration}
<div className="font-size-10">
{i18n.label_no_of_lines}:{" "}
{props.runningFile.totalNoOfLines}
</div>
<div className="font-size-10">{i18n.label_archived_on}: {getFormattedDate(props.runningFile.createdTime)}</div>
</div>
</div>
{ Array.isArray(hunks) && hunks.length ? (
<div className="diff-div">
<Diff
viewType="split"
diffType={type}
hunks={hunks}
tokens={tokens}
>
{hunks =>
hunks.map(hunk => <Hunk key={hunk.content} hunk={hunk} />)
}
</Diff>
</div>
) : (
<div className="div-margin-diff">
{statusDisplayDetails}
<span>{compareWith === "running" ? i18n.label_running_config_compliant : i18n.label_running_startup_config_compliant}</span>
</div>
)
}
</div>
) : (
<div className="loading-icon">
<DnxLoader color="#026E97" size="54" label="Loading..." />
</div>
)}
</div>
);
};
export default DiffViewer;
有人可以指出什么问题吗?