React 中弹出窗口关闭后按钮未禁用

问题描述 投票:0回答:2

我正在尝试实现一项功能,其中单击按钮后,应打开一个弹出窗口,其中包含一些内容,一旦关闭,该按钮应永久禁用。

现在,我已经为另一个按钮实现了相同的功能,该按钮在同一组件中运行良好,使用:-

    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>

    )
}

为什么会出现这种情况?

有两种方法可以解决这个问题 ->

  1. Refs:-我尝试过使用它,但它不起作用,因为关闭模式后,ref 的值再次设置为 null,而按钮却没有;被禁用。

  2. 状态:-一个显而易见的解决方案,但我想在没有其他可用解决方案时使用它们。

javascript reactjs react-hooks dom-events
2个回答
0
投票

您应该在关闭弹出窗口后禁用该按钮,而不是打开它。我将使用

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;

堆栈闪电战


0
投票

要解决这个问题,您可以修改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;
};
© www.soinside.com 2019 - 2024. All rights reserved.