Too Many Re-Renders ReactJs



嗯,我试图基本上使用语音文本与反应语音识别包,我试图使一个按钮图标停止点击时,麦克风是关闭或打开时,它是关闭

我试了很多来解决这个问题,这是我的代码。

import React, { Component, useRef } from "react";
import firebase from "../firebase";
import { createSpeechlySpeechRecognition } from "@speechly/speech-recognition-polyfill";
import SpeechRecognition, {
useSpeechRecognition,
} from "react-speech-recognition";
var axios = require("axios").default;
export default function Chat() {
let messages = [{ main: "Hey there! Wassop", class: "left" }];
let messageRef = useRef();
const appId = "I_HAVE_MY_KEY_HERE";
const SpeechlySpeechRecognition = createSpeechlySpeechRecognition(appId);
SpeechRecognition.applyPolyfill(SpeechlySpeechRecognition);
const {
transcript,
listening,
browserSupportsSpeechRecognition,
isMicrophoneAvailable,
} = useSpeechRecognition();
const startListening = () =>
SpeechRecognition.startListening({ continuous: true });
function Mic() {
if (listening) {
return SpeechRecognition.stopListening()
} else {
return SpeechRecognition.abortListening()
}    
}
function onSend(e) {
let message = messageRef.current.value;
e.preventDefault();
document.getElementById("messages").innerHTML +=
"<div class='right'>" + message + "</div>";
if (message == "") {
alert("Field shall not be empty!");
}
var options = {
---API REQUEST----
};
axios
.request(options)
.then(function (response) {
messageRef.current.value = "";
messages.push({
main: response.data.cnt,
class: "left",
});
document.getElementById("messages").innerHTML +=
"<div class='left'>" + response.data.cnt + "</div>";
console.log(messages);
})
.catch(function (error) {
console.error(error);
});
}
return (
<div className="card">
<h1 className="text-2xl text-center font-bold">Chat Box</h1>
<p>Microphone: {listening ? "on" : "off"}</p>
<p>{transcript}</p>
<br />
<div id="messages">
{messages.map((message) => (
<div key={message.main} className={message.class}>
{message.main}
</div>
))}
</div>
<br />
<form onSubmit={onSend}>
<div class="relative flex w-2/4 flex-wrap items-stretch mb-3">
<span class="z-10 h-full leading-snug font-normal absolute text-center text-blueGray-300 absolute bg-transparent rounded text-base items-center justify-center w-8 pl-3 py-3">
<img src="https://img.icons8.com/external-flatart-icons-flat-flatarticons/64/000000/external-message-contact-flatart-icons-flat-flatarticons.png" />
</span>
<input
type="text"
ref={messageRef}
placeholder="Message"
class="px-3 py-3 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-sm border-0 shadow outline-none focus:outline-none focus:ring w-full pl-10"
/>
<span class="z-10 h-full leading-snug font-normal absolute text-center text-blueGray-300 absolute bg-transparent rounded text-base items-center justify-center w-8 right-0 pr-3 py-3 mic">
<img
src="https://img.icons8.com/material-rounded/24/000000/microphone.png"
onClick={Mic()}
/>
</span>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
Button
</button>
</form>
</div>
);
}

我得到了太多渲染的错误,我无法弄清楚如何修复我试着看了很多,但没有什么帮助,我甚至不能理解别人,请帮助我。

重渲染过多的原因

如果你像这样绑定你的onClick函数:

onClick={Mic()}

React将调用该函数,而不需要实际的点击。您应该使用onClick={Mic}onClick={() => Mic()}

你的代码还有其他几个问题:

1。使用ref

您正在使用useRef变量来保存消息useRef更新将不会触发重新呈现。相反,尝试使用useState钩子将变量绑定到状态变量

2。在功能组件内创建对象

您正在功能组件内创建messages对象。每次重新渲染时,这个messages对象将被初始化为相同的数组。将其绑定到state变量,以反映对messages对象所做的更改。

import {useState} from 'react'
const [messages, setMessages] = useState([{ main: "Hey there! Wassop", class: "left" }])

3。DOM操作

应该避免像

这样的DOM操作:
document.getElementById("messages").innerHTML +=  "<div class='right'>" + message + "</div>"; 

如果可能的话。在本例中,您可以使用refs并将其绑定到JSX。

const messageRef = useRef('')
return(
...
<div id="message" ref={messageRef}> ...
...
)

我强烈建议阅读更多关于React生命周期和钩子的内容:

<标题>文档

相关内容

最新更新