【发布时间】:2020-11-04 04:18:53
【问题描述】:
我创建了一个 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, { useState, FormEvent, useEffect, 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);
【问题讨论】:
-
如果您发布此sandbox,那就太好了。或者在那里创建最小 poc。这里有很多代码。沙盒会是更好的选择。其他人可以在那里查看和玩。
-
<HocComponent props={{ ...props, output, loading }} />似乎将您的道具嵌套在名为props的道具中,即props.props.output等... -
@DrewReese 不错。应该写成
<HocComponent {...props} output={output} loading={loading} />
标签: javascript reactjs react-hooks react-state-management