Javascript 当我尝试更新状态中的数组时,React应用程序变为空白
我试图通过语音操作React应用程序中显示的图像。我实施了SR,效果很好:Javascript 当我尝试更新状态中的数组时,React应用程序变为空白,javascript,reactjs,Javascript,Reactjs,我试图通过语音操作React应用程序中显示的图像。我实施了SR,效果很好: <button onClick={SpeechRecognition.startListening}>Start</button> 只要说出的单词是“kitten”,加载图像的数组就会以这种方式更新: if(transcript == "kitten") { const newImages = loadImages.concat({image: 'htt
<button onClick={SpeechRecognition.startListening}>Start</button>
只要说出的单词是“kitten”,加载图像的数组就会以这种方式更新:
if(transcript == "kitten")
{
const newImages = loadImages.concat({image: 'https://www.onlinekittencare.com/wp-content/uploads/2020/07/vChK6pTy3vN3KbYZ7UU7k3-1200-80.jpg'})
setLoadImages(newImages);
}
您看到的成绩单是一个变量,我在这里初始化了它:
const {transcript} = useSpeechRecognition();
在渲染中,我使用它来显示SR理解的内容,因此如果我说“hello”,它将显示“hello”:
问题是,每当我说“kitten”(如上所述,它被用作将图片添加到数组loadImages
)的命令)时,我的React应用程序就会变为空白。在inspect中,我还可以看到它说react dom.development.js:14997 Uncaught Error:重新渲染太多。React限制渲染的数量以防止无限循环。
我该如何解决这个问题
编辑(我添加了整个代码):
函数应用程序(){
常量[矩形,设置矩形]=useState([]);
const[circles,setCircles]=useState([]);
const[selectedId,selectShape]=useState(null);
const[shapes,setShapes]=useState([]);
const[,updateState]=React.useState();
const stageEl=React.createRef();
const layerEl=React.createRef();
const fileUploadEl=React.createRef();
const[brushSize,setBrushSize]=React.useState('5');
常量[isDrawing,setIsDrawing]=React.useState(false);
const dragUrl=React.useRef();
//const stageRef=React.useRef();
const[images,setImages]=React.useState([]);
const[loadImages,setLoadImages]=React.useState([]);
const getRandomInt=max=>{
返回Math.floor(Math.random()*Math.floor(max));
};
const{transcript}=useSpeechRecognition();
常量URLImage=({image})=>{
const[img]=useImage(image.src);
返回(
);
};
常量抽绳=()=>{
setIsDrawing(真);
if(isDrawing){
addLine(stageEl.current.getStage(),layerEl.current,brushSize);
};
};
常量行=()=>{
addLine(stageEl.current.getStage(),layerEl.current,brushSize,“擦除”);
};
常量addRectangle=()=>{
setIsDrawing(假);
常数rect={
x:getRandomInt(100),
y:getRandomInt(100),
宽度:100,
身高:100,
填充:“红色”,
id:`rect${rectangles.length+1}`,
};
const rects=矩形。concat([rect]);
设置矩形(矩形);
const shs=shapes.concat([`rect${rectangles.length+1}`]);
设置形状(shs);
};
const forceUpdate=React.useCallback(()=>updateState({}),[]);
常量撤消=()=>{
const lastId=shapes[shapes.length-1];
让index=circles.findIndex(c=>c.id==lastId);
如果(索引!=-1){
圆形拼接(索引1);
设置圆(圆);
}
索引=矩形.findIndex(r=>r.id==lastId);
如果(索引!=-1){
矩形.拼接(索引1);
设置矩形(矩形);
}
index=images.findIndex(r=>r.id==lastId);
如果(索引!=-1){
图像拼接(索引,1);
设置图像(图像);
}
shapes.pop();
设置形状(形状);
forceUpdate();
};
document.addEventListener(“向下键”,ev=>{
如果(ev.code==“删除”){
让index=circles.findIndex(c=>c.id==selectedId);
如果(索引!=-1){
圆形拼接(索引1);
设置圆(圆);
}
索引=矩形.findIndex(r=>r.id==selectedId);
如果(索引!=-1){
矩形.拼接(索引1);
设置矩形(矩形);
}
index=images.findIndex(r=>r.id==selectedId);
如果(索引!=-1){
图像拼接(索引,1);
设置图像(图像);
}
forceUpdate();
}
});
如果(成绩单==“小猫”)
{
const newImages=loadImages.concat({image:'https://www.onlinekittencare.com/wp-content/uploads/2020/07/vChK6pTy3vN3KbYZ7UU7k3-1200-80.jpg'})
setLoadImages(newImages);
}
返回(
{loadImages.map(image=>(
{
dragUrl.current=e.target.src;}
/>
))}
{
e、 预防默认值();
//寄存器事件位置
stageEl.current.设定点位置(e);
//添加图像
设置图像(
海螺([
{
…stageEl.current.getPointerPosition(),
src:dragUrl.current,
},
])
);
}}
onDragOver={(e)=>
e、 预防默认值()
}
>
白板
矩形
圆圈
线
擦除
{
目标大小(如目标值);
抽绳();
}}
>
5.
20
50
正文
形象
撤消
转录本:{transcript}
开始
{
//单击空白区域时取消选择
const clickednepty=e.target==e.target.getStage();
如果(单击nempty){
选择形状(空);
}
}}
>
{矩形.map((矩形,i)=>{
返回(
{
//选择形状(矩形id);
//}}
onChange={newAttrs=>{
常量矩形=矩形。切片();
rects[i]=newAttrs;
设置矩形(矩形);
}}
/>
);
})}
{images.map((图像)=>{
返回;
})}
);
}
导出默认应用程序;
根据您共享的代码,如果成绩单等于kitten,则与您如何更新状态有关
基本上,您编写的逻辑是,在呈现时,如果转录本是kitten,则更新状态。但是,当您更新状态时,将重新渲染,并再次点击该逻辑。。。再一次。。。一次又一次。解决方案
const {transcript} = useSpeechRecognition();
<p id="transcript">Transcript: {transcript}</p>
{images.map((image) => {
return <URLImage image={image}/>;
})}
function App() {
const [rectangles, setRectangles] = useState([]);
const [circles, setCircles] = useState([]);
const [selectedId, selectShape] = useState(null);
const [shapes, setShapes] = useState([]);
const [, updateState] = React.useState();
const stageEl = React.createRef();
const layerEl = React.createRef();
const fileUploadEl = React.createRef();
const [brushSize, setBrushSize] = React.useState('5');
const [isDrawing, setIsDrawing] = React.useState(false);
const dragUrl = React.useRef();
//const stageRef = React.useRef();
const [images, setImages] = React.useState([]);
const [loadImages, setLoadImages] = React.useState([]);
const getRandomInt = max => {
return Math.floor(Math.random() * Math.floor(max));
};
const {transcript} = useSpeechRecognition();
const URLImage = ({image}) => {
const [img] = useImage(image.src);
return (
<Image
image = {img}
x = {image.x}
y = {image.y}
offsetX = {50}
offsetY = {50}
width={200}
height={200}
draggable
/>
);
};
const drawLine = () => {
setIsDrawing(true);
if(isDrawing){
addLine(stageEl.current.getStage(), layerEl.current, brushSize);
};
};
const eraseLine = () => {
addLine(stageEl.current.getStage(), layerEl.current, brushSize, "erase");
};
const addRectangle = () => {
setIsDrawing(false);
const rect = {
x: getRandomInt(100),
y: getRandomInt(100),
width: 100,
height: 100,
fill: "red",
id: `rect${rectangles.length + 1}`,
};
const rects = rectangles.concat([rect]);
setRectangles(rects);
const shs = shapes.concat([`rect${rectangles.length + 1}`]);
setShapes(shs);
};
const forceUpdate = React.useCallback(() => updateState({}), []);
const undo = () => {
const lastId = shapes[shapes.length - 1];
let index = circles.findIndex(c => c.id == lastId);
if (index != -1) {
circles.splice(index, 1);
setCircles(circles);
}
index = rectangles.findIndex(r => r.id == lastId);
if (index != -1) {
rectangles.splice(index, 1);
setRectangles(rectangles);
}
index = images.findIndex(r => r.id == lastId);
if (index != -1) {
images.splice(index, 1);
setImages(images);
}
shapes.pop();
setShapes(shapes);
forceUpdate();
};
document.addEventListener("keydown", ev => {
if (ev.code == "Delete") {
let index = circles.findIndex(c => c.id == selectedId);
if (index != -1) {
circles.splice(index, 1);
setCircles(circles);
}
index = rectangles.findIndex(r => r.id == selectedId);
if (index != -1) {
rectangles.splice(index, 1);
setRectangles(rectangles);
}
index = images.findIndex(r => r.id == selectedId);
if (index != -1) {
images.splice(index, 1);
setImages(images);
}
forceUpdate();
}
});
if(transcript == "kitten")
{
const newImages = loadImages.concat({image: 'https://www.onlinekittencare.com/wp-content/uploads/2020/07/vChK6pTy3vN3KbYZ7UU7k3-1200-80.jpg'})
setLoadImages(newImages);
}
return (
<div className="home-page">
{loadImages.map(image => (
<img id="img" className="img"
src={image.image}
width="200"
height="200"
onDragStart={(e) => {
dragUrl.current = e.target.src;}}
/>
))}
<div
onDrop={(e) => {
e.preventDefault();
// register event position
stageEl.current.setPointersPositions(e);
// add image
setImages(
images.concat([
{
...stageEl.current.getPointerPosition(),
src: dragUrl.current,
},
])
);
}}
onDragOver={(e) =>
e.preventDefault()
}
>
<h1>Whiteboard</h1>
<button onClick={addRectangle}>
Rectangle
</button>
<button>
Circle
</button>
<button onClick={drawLine}>
Line
</button>
<button onClick={eraseLine}>
Erase
</button>
<select
value={brushSize}
onChange={(e) => {
setBrushSize(e.target.value);
drawLine();
}}
>
<option value="5">5</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
<button variant="secondary">
Text
</button>
<button variant="secondary">
Image
</button>
<button variant="secondary" onClick={undo}>
Undo
</button>
<p id="transcript">Transcript: {transcript}</p>
<button onClick={SpeechRecognition.startListening}>Start</button>
<Stage
width={window.innerWidth * 0.9}
height={window.innerHeight - 150}
ref={stageEl}
dragabble
onMouseDown={e => {
// deselect when clicked on empty area
const clickedOnEmpty = e.target === e.target.getStage();
if (clickedOnEmpty) {
selectShape(null);
}
}}
>
<Layer ref={layerEl}>
{rectangles.map((rect, i) => {
return (
<Rectangle
key={i}
shapeProps={rect}
isSelected={rect.id === selectedId}
//onSelect={() => {
// selectShape(rect.id);
//}}
onChange={newAttrs => {
const rects = rectangles.slice();
rects[i] = newAttrs;
setRectangles(rects);
}}
/>
);
})}
{images.map((image) => {
return <URLImage image={image}/>;
})}
</Layer>
</Stage>
</div>
</div>
);
}
export default App;
React.useEffect(() => {
if (transcript === "kitten") {
const newImages = loadImages.concat({image: 'https://www.onlinekittencare.com/wp-content/uploads/2020/07/vChK6pTy3vN3KbYZ7UU7k3-1200-80.jpg'})
setLoadImages(newImages);
}
}, [transcript]);