加载React组件触发Too many re-renders 如何优化动态Material Icon按钮
问题根因
你遇到的无限重渲染问题完全来自AddDelete.js里Button的onClick属性写法错误:
// 错误写法:渲染时直接执行状态更新函数,触发state更新→再次渲染→再执行,形成死循环 onClick={changeMethod(!props.course.saved)}
onClick需要接收一个函数引用,而你直接调用了状态更新函数changeMethod,组件每渲染一次就会执行一次状态更新,React检测到无限循环就抛出了你看到的报错。
同时你的代码还存在两个逻辑问题:
- 课程保存状态的字段名是
isSaved,但代码中错误写为props.course.saved,字段不匹配会导致状态判断错误 - 点击切换状态后没有调用
changeSaveStatus接口同步后端状态 - 未使用的
courseList状态可以删除
修正后的实现代码
import React, { useState } from 'react'; import FavoriteIcon from '@material-ui/icons/Favorite'; import DeleteIcon from '@material-ui/icons/Delete'; import { Button, makeStyles } from '@material-ui/core'; import axios from 'axios'; const useStyles = makeStyles({ icon: { color: "#0479a8", fontSize: "400%" } }); const changeSaveStatus = (id, trueFalse) => { const params = { "id": parseInt(id), "bool": trueFalse } axios.put('http://localhost:5000/saved-courses', params) } export function AddDelete(props) { const classes = useStyles(); // 初始化状态用props传入的isSaved字段 const [isSaved, setIsSaved] = useState(props.course.isSaved); // 封装点击事件,仅在用户点击时执行 const handleToggleSave = () => { const newStatus = !isSaved; setIsSaved(newStatus); // 同步最新状态到后端 changeSaveStatus(props.course._id, newStatus); } return ( <div> <Button style={{borderRadius: "50%"}} onClick={handleToggleSave}> {isSaved ? <DeleteIcon className={classes.icon} /> : <FavoriteIcon className={classes.icon} />} </Button> </div> ); }
额外优化建议
CoursePage.js里的useEffect依赖项要加上url,避免路由切换courseId时不会重新拉取课程数据:
useEffect(() => { axios.get(url).then( (selectedCourse) => { setCourse(selectedCourse.data); setLoading(false); } ) }, [url])
内容的提问来源于stack exchange,提问作者jedschlo14
相关产品推荐
相关产品推荐

