React useEffect中componentMounted变量丢失及按钮不显示问题求助
问题修复方案
你的代码存在三个核心问题,导致出现警告且按钮无法显示,以下是针对性修复:
1. 解决componentMounted的变量丢失警告
原代码中componentMounted是普通变量,每次组件渲染都会重新初始化,无法跨渲染保留状态。按照提示改用useRef存储这个可变标记:
- 导入
useRef - 用
const componentMounted = useRef(true)替代let componentMounted = true - 访问时使用
componentMounted.current
2. 修复无限循环导致的Loading一直显示问题
原useEffect没有设置依赖数组,会在组件每次渲染时重复执行,导致loading被反复设为true。给useEffect添加空依赖数组[],确保仅在组件挂载时执行一次数据请求。
3. 修正数据处理的小问题
原代码中console.log(filter)会打印初始空数组,因为setFilter是异步更新;另外可以优化filter的初始值,直接设为空数组即可。
修改后的完整代码
import React, { useState, useEffect, useRef } from "react"; const Products = () => { const [data, setData] = useState([]); const [filter, setFilter] = useState([]); const [loading, setLoading] = useState(false); const componentMounted = useRef(true); // 用useRef保存状态 useEffect(() => { const getProducts = async () => { setLoading(true); try { const response = await fetch("https://fakestoreapi.com/products"); const products = await response.json(); if (componentMounted.current) { setData(products); setFilter(products); setLoading(false); } } catch (error) { console.error("数据请求失败:", error); if (componentMounted.current) { setLoading(false); } } }; getProducts(); // 组件卸载时标记为false return () => { componentMounted.current = false; }; }, []); // 添加空依赖数组,仅执行一次 const Loading = () => { return <>Loading...</>; }; const ShowProducts = () => { return ( <> <div className="button"> <button className="btn btn-outline-dark me-2">All</button> <button className="btn btn-outline-dark me-2">Men's Clothing</button> <button className="btn btn-outline-dark me-2">Women's Clothing</button> <button className="btn btn-outline-dark me-2">Jewelery</button> <button className="btn btn-outline-dark me-2">Electronics</button> </div> </> ); }; return ( <> <div className="container my-5"> <div className="row"> <div className="col-12"> <h1 className="display-6 fw-bolder text-center">Latest Products</h1> <hr /> </div> </div> <div className="row justify-content-center"> {loading ? <Loading /> : <ShowProducts />} </div> </div> </> ); }; export default Products;
额外说明
- 添加了
try/catch捕获请求异常,避免请求失败时loading一直处于true状态 - 移除了多余的
response.clone(),直接解析一次JSON即可,减少不必要的资源消耗
内容的提问来源于stack exchange,提问作者Engr. Rana Sikandar Khan
相关产品推荐
相关产品推荐

