React错误:只能在函数组件的主体内部调用挂钩

时间:2019-12-04 10:34:55

标签: reactjs react-hooks react-16

我知道这是一个非常常见的错误, 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;

有人可以指出是什么问题吗?

0 个答案:

没有答案