You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件useEffect未触发求助:同写法两组件表现不一致

问题描述

我找不到代码出现问题的原因。我有两个实现了state与useEffect的JSX组件,其中一个组件能正常触发useEffect,另一个却不能,且两者的state和useEffect定义方式完全相同,恳请帮助。

未触发useEffect的组件:reviewDeckRoute.jsx

import React from 'react'
import axios from 'axios'
import FlashcardParent from '../flashcard/flashcardParent'

const ReviewDeckRoute = ({deckID}) => {
    const url = 'http://localhost:8080/api/deck/' + deckID

    const [deckInfo, setDeckInfo] = React.useState([])

    React.useEffect(() => {
        console.log("CALLED API")
        axios.get(url).then((response) => {
            setDeckInfo(response.data)
        })
    }, [])
    
    return (
        <div className="wrapper">
            <h1>Review Flashcards</h1>
            <FlashcardParent deckInfo={deckInfo} />
        </div>
    )
}

export default ReviewDeckRoute;

正常触发useEffect的组件:editDeckRoute.jsx

import React from "react"
import axios from "axios"
import EditFlashcard from "../editFlashcard/editFlashcard"

const EditDeckRoute = ({deckID}) => {
    const url = "http://localhost:8080/api/deck/" + deckID
    
    const [deckInfo, setDeckInfo] = React.useState([])

    React.useEffect(() => {
        axios.get(url).then((response) => {
            setDeckInfo(response.data)
        })
    }, [])

    function newCard() {
        const tmpDeck = new Map()
        tmpDeck.set("topic", "")
        tmpDeck.set("description", "")
        tmpDeck.set("id", deckInfo.length++)

        // create brand new array. loop through deckInfo and add elements to new array
        let tmpArr = []
        deckInfo.map((card) => {
            tmpArr.push(card)
        })
        tmpArr.push(tmpDeck)

        setDeckInfo(tmpArr)
    }

    function handleDeckInfoChange(index, e) {
        console.log(`${[e.target.name]}: ${e.target.value} ${index} `)
        setDeckInfo(prevState => ({
            ...prevState.map(card => ({
                ...card = new Map(Object.entries(card)),
                ...card.get("id") === index
                ? card.set([e.target.name], e.target.value)
                : card
            }))
        }))
    }

    
    return (
        <>
            <div className="wrapper">
                <div className="header">
                    <h1>Edit Flashcards</h1>
                    <button onClick={newCard} >Add Card</button>
                </div>
                {deckInfo.map((flaschard, num) => {
                        return <EditFlashcard key={num} index={num} flaschard={flaschard} change={handleDeckInfoChange} />
                    }
                )}

            </div>
        </>
    )
}

export default EditDeckRoute;

排查与解决思路

1. 先确认组件是否真的挂载了

空依赖的useEffect只会在组件挂载时执行一次,如果ReviewDeckRoute压根没被渲染,自然不会触发。

  • 快速验证:在ReviewDeckRoute组件最顶部加一行console.log("ReviewDeckRoute 已加载"),查看控制台是否有输出。如果没有,直接检查路由配置或父组件的条件渲染逻辑,确认组件的路径是否匹配、是否满足显示条件。

2. 检查组件是否被快速卸载

如果控制台出现了组件挂载的日志,但看不到CALLED API,大概率是组件挂载后又立即被卸载了(比如父组件状态快速变化、路由跳转逻辑错误)。

  • 补充验证:在useEffect中添加卸载监听:
    React.useEffect(() => {
        console.log("CALLED API")
        axios.get(url).then((response) => {
            setDeckInfo(response.data)
        })
        
        return () => {
            console.log("ReviewDeckRoute 已卸载")
        }
    }, [])
    
    如果挂载日志后紧接着出现卸载日志,就去上层组件找状态或路由跳转的问题。

3. 检查deckID参数有效性

如果组件确实挂载且未被卸载,但请求没生效,检查deckID是否为undefined:

  • 如果deckID为空,url会拼接成http://localhost:8080/api/deck/undefined,导致请求失败,但useEffect本身还是会执行,控制台会出现CALLED API日志,这时去网络面板查看请求错误信息即可。

4. 排除React严格模式干扰

开发环境下的React严格模式会让useEffect执行两次,但不会导致完全不触发。可以暂时注释掉根组件的<React.StrictMode>标签测试,看是否有变化。


内容的提问来源于stack exchange,提问作者Grant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:57:23