微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从HOC收到道具后状态未正确更改

如何解决从HOC收到道具后状态未正确更改

我创建了一个HOC来处理套接字设置+处理程序所需的所有逻辑,并将我的组件包装到其中,同时传递HOC的状态。我从包装的组件中添加了useEffect,以在从HOC获取新道具后更改其状态。问题是,即使它在控制台中正确记录了这些道具,它还是以某种方式损坏了。即使在获得道具后也不会显示输出,并且尽管加载状态从一开始就设置为false,但是加载微调器一直在工作。有谁知道可能是什么原因造成的,我该如何解决

HOC:

import React,{ useState,useEffect,useContext } from "react";
import SocketContext from "../../components/sockets/socketContext";
import axios from "axios";
import { SentimentOutput } from "./../../types/outputTypes";
import { TaskLoading } from "./../../types/loadingTypes";




export default function withSocketActions(HocComponent: any) {
    return (props: any) => {
        const [output,setoutput] = useState({
            score: undefined,label: undefined,});
        const [loading,setLoading] = useState(false);

        const contextProps = useContext(SocketContext);

        useEffect(() => {
            if (contextProps) {
                const { socket } = contextProps;
                socket.on("status",(data: any) => {
                    if (
                        data.message.status === "processing" ||
                        data.message.status === "pending"
                    ) {
                        setLoading(true);
                        console.log(data);
                    } else if (data.message.status === "finished") {
                        setLoading(false);
                        getoutput(data.message.task_id);
                        console.log(data);
                    }
                });
                return () => {
                    socket.off("");
                };
            }
        },[]);

        const getoutput = async (id: string) => {
            const response = await axios.get(`http://localhost:9876/result/${id}`);
            console.log("Output: ",response.data);
            setoutput(response.data);
        };

        return (
            <>
                <HocComponent props={{ ...props,output,loading }} />
            </>
        );
    };
}

组件:

import React,FormEvent,useContext } from "react";
import axios from "axios";
import pulseLoader from "react-spinners/pulseLoader";
import { faTag,faPoll } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import withSocketActions from "../../components/sockets/withSocketActions";

import "../../styles/containers.scss";
import "../../styles/buttons.scss";
import "../../styles/text.scss";

function SentimentInput(props: any) {
    const [input,setInput] = useState("");
    const [output,setoutput] = useState({
        score: "",label: "",});
    const [loading,setLoading] = useState(false);

    useEffect(() => {
        setoutput({ score: props.output?.score,label: props.output?.label });
        setLoading(props.loading);
        console.log("OUTPUT: ",props);
    },[props]);

    const getHighlightColour = (label: string | undefined) => {
        if (label === "POSITIVE") return "#57A773";
        else if (label === "NEGATIVE") return "#F42C04";
        else return "transparent";
    };

    const submitInput = async (input: string) => {
        let formData = new FormData();
        formData.set("text",input);
        if (props.model) formData.set("model",props.model);
        const response = await axios.post(
            `http://localhost:9876/run/sentiment_analysis`,formData
        );
        console.log("RESPONSE: ",response.data.id);
    };

    const handleSubmit = async (e: FormEvent<HTMLButtonElement>) => {
        e.preventDefault();
        console.log(input);
        const result = await submitInput(input);
    };

    return (
        <div className="inputContainer">
            <div style={{ width: "100%",height: "100%",justifyContent: "center" }}>
                <textarea
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    rows={25}
                    className={"inputArea"}
                    readOnly={loading}
                    style={{
                        BoxShadow: `0 0 12px 2px ${getHighlightColour(
                            output && output.label
                        )}`,}}
                    autoFocus
                    placeholder={"Insert text for evaluation"}
                />
                <button
                    className={"submitInputButton"}
                    onClick={(e) => handleSubmit(e)}
                >
                    <div className={"topButtonText"}>Evaluate</div>
                </button>
                <pulseLoader loading={loading} color={"white"} size={6} />

                {output &&
                    output.score !== undefined &&
                    output.label !== undefined &&
                    !loading && (
                        <div
                            style={{
                                marginTop: "10px",display: "flex",justifyContent: "center",}}
                        >
                            <FontAwesomeIcon
                                icon={faTag}
                                size={"lg"}
                                color={"#f0edee"}
                                style={{ paddingRight: "5px" }}
                            />
                            <div
                                className={
                                    output && output.label === "POSITIVE"
                                        ? "outputInfo labelPositive"
                                        : "outputInfo labelNegative"
                                }
                            >
                                {output.label}
                            </div>

                            <FontAwesomeIcon
                                icon={faPoll}
                                size={"lg"}
                                color={"#f0edee"}
                                style={{ paddingRight: "5px" }}
                            />
                            <div className={"outputInfo"}>{output.score}</div>
                        </div>
                    )}
            </div>
        </div>
    );
}

export default withSocketActions(SentimentInput);

解决方法

写@Drew的评论作为答案

<HocComponent props={{ ...props,output,loading }} />
看起来是将您的道具嵌套在名为props的道具中,即props.props.output
更改为-
<HocComponent {...props} output={output} loading={loading} />

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。