Hello :)

Alors voila j'ai un soucis avec un projet sur NextJS et ChatGPT

J'ai deux states, un prompt et un thread, le premier sert à récupérer la valeur d'un input texte, et le deuxième c'est un array avec toute la discution

Je modifie le thread deux fois, une fois pour y mettre le prompt, et une autre fois pour mettre le texte généré par ChatGPT, le soucis c'est que tout se fait en même temps, ce qui fait que la réponse de ChatGPT vient écraser le prompt

J'ai essayé d'utiliser des fonction asynchrones avec des await, des Promises, mais NextJS refuse de me laisser faire (oui oui l'erreur que je reçois c'est "nan t'as pas le droit de faire ça, utilises useEffect")

Alors j'ai bien voulu utiliser useEffect, mais le problème c'est que en callback je veux lancer une call API vers ChatGPT, et si je lance cet appel, le texte de ChatGPT va s'ajouter au fil, ce qui va déclencher le useEffect, bref la spirale infernale :D, et comme mon projet à la base ce n'est pas de reproduire le Chat d'openai mais d'utiliser d'autres outils tous payants ça va piquer niveau facture si je fait une boucle infinie ^^'

Bref vous avez une solution? Soit une solution pour ne déclencher useEffect QUE quand c'est le prompt qui est pushé dans le thread (ah oui au fait j'ai essayé de faire un setThread({thread.length: {user: "user"/"AI", text: "..."}}) ça aurait pu être une solution, interdit aussi, en object comme en array key => value ^^) soit une alternative à useEffect (c'est bien beau d'interdire les Promises, mais si ont n'a pas d'autres alternatives que useEffect qui a un usage trop restrictif...)

Ah oui au fait j'ai déjà fais setThread(prompt, callback), depuis React 18 il n'y a plus de callback dans le setState, mais un message d'erreur qui dit "utilises useEffect, c'est tro bien useEffect"

Et voici le code:

const Chatbot = () => {
    const [prompt, setPrompt] = useState("")
    const [thread, setThread] = useState([])
    let componentDidMount = useRef(false)

    useEffect(() => {
        if (componentDidMount.current > 1) { // un truc temporaire pour bypass le double render du strictmode
            setPrompt('')
        } else componentDidMount.current ++
    }, [thread])

    const handleCLick = async () => {
        setThread([...thread, prompt])
        // callOpenAi(prompt) Inutilisable tant que je n'ai pas fais un truc stable :(
    }

    // ...
}

Voila merci ^^

1 réponse


popotte
Auteur

Ok alors j'ai trouvé un truc, si quelqu'un a un moyen plus "propre" j'aimerais bien savoir, mais pour l'instant ça fait le taf ^^'
En gros l'array.... Dans un array, la technique de la poupée russe ça passe bien

    setThread([...thread, [{"user": "human", "text": prompt}]])
    setThread([...thread, [{"user": "AI", "text": response.data.choices[0].text}]])

    useEffect(() => {
        if (componentDidMount.current > 1) {
            if (thread.slice(-1)[0][0].user === "human") {
                console.log('Human')
                callOpenAi()
            } else { console.log('AI') }
        } else componentDidMount.current ++
    }, [thread])