我正在尝试实现一项功能,其中单击按钮后,应打开一个弹出窗口,其中包含一些内容,一旦关闭,该按钮应永久禁用。
现在,我已经为另一个按钮实现了相同的功能,该按钮在同一组件中运行良好,使用:-
const fiftyClickHandler = (event) => {
event.currentTarget.disabled = true;
setIsFiftyActive(true);
}
但它对其他按钮不起作用(询问专家)
import React from 'react'
import OpenAI from "openai";
import Popup from "./Popup";
export default function Helpline({ data, questionNumber, setIsFiftyActive }) {
//* Open source API key
const openai = new OpenAI({
apiKey: process.env.REACT_APP_API_KEY,
baseURL: process.env.REACT_APP_BASE_URL,
dangerouslyAllowBrowser: true
});
const [PopupModalOpen, setPopupModalOpen] = React.useState(false)
const [gptData, setGptData] = React.useState([]);
const expertClickHandler = async (event) => {
//* Constructing object that would have all answer options and questions to be sent to GPT
let ansOptions = "";
data[questionNumber - 1].answers.map((item) => {
return ansOptions += item.text + ",";
})
let contentObj = {
ansOptions,
question: data[questionNumber - 1].question
}
try {
const completion = await openai.chat.completions.create({
model: "pai-001",
messages: [
{ role: "system", content: "You are an expert in trivia and general knowledge and are an assistant in a quiz show helping users when they are in need" },
{
role: "user",
content: contentObj,
},
],
});
setGptData(completion.choices[0].message.content);
console.log(gptData);
} catch (error) {
setGptData("Null");
console.log("Error fetching results")
}
setPopupModalOpen(true);
event.currentTarget.disabled = true;
}
const fiftyClickHandler = (event) => {
event.currentTarget.disabled = true;
setIsFiftyActive(true);
}
return (
PopupModalOpen ?
<div>
<Popup PopupModalOpen={PopupModalOpen} setPopupModalOpen={setPopupModalOpen} />
</div> :
//* Expert answer state === false meaning modal is not open */
<div className="helpline">
<button className="game-btn" id="fifty-fifty" onClick={fiftyClickHandler}>
Fifty Fifty
</button>
<button className="game-btn" id="ask-the-expert" onClick={expertClickHandler}>
Ask the expert
</button>
</div>
)
}
为什么会出现这种情况?
有两种方法可以解决这个问题 ->
Refs:-我尝试过使用它,但它不起作用,因为关闭模式后,ref 的值再次设置为 null,而按钮却没有;被禁用。
状态:-一个显而易见的解决方案,但我想在没有其他可用解决方案时使用它们。
您应该在关闭弹出窗口后禁用该按钮,而不是打开它。我将使用
useRef
钩子来创建 buttonRef
。我会使用 useStateCallback
钩子创建弹出窗口的状态,因为我可以使用 setState(newState, () => { /** after state and component updated */})
这是一个例子:
import React, { useCallback, useEffect, useRef, useState } from 'react';
export function useStateCallback<T>(
initialState: T
): [T, (state: T, cb?: (state: T) => void) => void] {
const [state, setState] = useState(initialState);
const cbRef = useRef<((state: T) => void) | undefined>(undefined);
const setStateCallback = useCallback((state: T, cb?: (state: T) => void) => {
cbRef.current = cb;
setState(state);
}, []);
useEffect(() => {
if (cbRef.current) {
cbRef.current(state);
cbRef.current = undefined;
}
}, [state]);
return [state, setStateCallback];
}
function App() {
const [PopupModalOpen, setPopupModalOpen] = useStateCallback(false);
const buttonRef = React.useRef<HTMLButtonElement>(null);
const expertClickHandler = () => {
setPopupModalOpen(true);
};
return PopupModalOpen ? (
<dialog
open={PopupModalOpen}
onClick={() =>
setPopupModalOpen(false, () => {
if (buttonRef.current) {
buttonRef.current.disabled = true;
}
})
}
>
content
</dialog>
) : (
<button ref={buttonRef} onClick={expertClickHandler}>
Ask the expert
</button>
);
}
export default App;
要解决这个问题,您可以修改expertClickHandler函数以确保弹出窗口关闭后永久禁用该按钮。
const expertClickHandler = async (event) => {
try {
// Construct object and send request to GPT API
let ansOptions = "";
data[questionNumber - 1].answers.map((item) => {
return ansOptions += item.text + ",";
});
let contentObj = {
ansOptions,
question: data[questionNumber - 1].question
};
const completion = await openai.chat.completions.create({
model: "pai-001",
messages: [
{ role: "system", content: "You are an expert in trivia and general knowledge and are an assistant in a quiz show helping users when they are in need" },
{ role: "user", content: contentObj },
],
});
setGptData(completion.choices[0].message.content);
console.log(gptData);
} catch (error) {
setGptData("Null");
console.log("Error fetching results");
}
setPopupModalOpen(true);
// Disable the button
event.currentTarget.disabled = true;
};