Django REST+React博客项目useEffect无限循环排查及代码优化求助
问题修复及代码优化建议
一、useEffect无限循环问题根源及修复
你的useEffect将posts设置为依赖项,但effect内部又调用setPosts更新posts的值,每次posts更新都会重新触发effect执行,直接形成死循环。
修复方案:
如果只需要页面初始化时加载一次文章列表,把依赖项改成空数组[]即可,同时要注意不要直接给useEffect的回调加async,会返回promise违反useEffect回调只能返回清理函数的规则,调整后代码如下:
useEffect(() => { const fetchPosts = async () => { const response = await fetch('http://127.0.0.1:8000/api/post-list/') setPosts(await response.json()) } fetchPosts() }, [])
如果需要增删改操作后自动刷新列表,可以额外加一个刷新触发器的状态:
const [refreshFlag, setRefreshFlag] = useState(0) // useEffect依赖改为refreshFlag useEffect(() => { // 拉取列表逻辑不变 }, [refreshFlag]) // 每次增删改操作成功后调用setRefreshFlag(prev => prev + 1)即可触发列表刷新
二、其他代码优化点
- 修复
editData初始值类型错误:当前editData初始值是数组,但实际存储的是文章对象,改为useState({})更合理 - 避免用
index作为列表key:如果文章列表有增删操作,用index做key会导致DOM复用异常,直接用post.id作为key即可:
{posts.map((post) => { return( <div key={post.id} className="list-group-item list-group-item-dark mb-1"> {/* 其余内容不变 */} </div> ) })}
- 修复fetch请求成功后无后续处理的问题:当前新增、编辑、删除请求发送成功后,页面列表不会自动更新,以删除逻辑为例调整如下:
const handleDelete = async (post) => { await fetch(`http://127.0.0.1:8000/api/post-delete/${post.id}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', } }) // 删除成功后直接更新本地列表,不用重新拉取接口 setPosts(prev => prev.filter(item => item.id !== post.id)) }
- 修复
handleSubmit里的then用法错误:当前.then(setCreate(...))是直接同步执行setCreate,不是等请求成功后执行,调整如下:
fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(create) }) .then(res => res.json()) .then(() => { setCreate({ title: "", description: "", completed: false }) setEditing(false) // 新增:重置编辑状态 setRefreshFlag(prev => prev + 1) // 触发列表刷新 })
- 统一属性命名:React里用
className代替原生HTML的class属性,当前代码多处混用,建议统一修改避免潜在问题 - 删除冗余语法:
handleEdit里{setEditing(true)}、{setEditData(post)}外层的大括号是多余的,直接写方法调用即可
内容的提问来源于stack exchange,提问作者naveed
相关产品推荐
相关产品推荐

