React组件状态提升问题:首次点击时接收组件状态未更新
问题解决:React状态提升首次点击不更新的问题
问题根源
- React状态更新的异步特性:在
HeaderBar的点击事件里,调用set_state("oppened")后立刻通过props.throwData(state)传递状态,但此时state还未完成更新,传递的是初始的undefined,导致父组件首次点击时接收不到正确值。 - 无效的useEffect逻辑:
HeaderBar中的useEffect依赖state,但内部又调用set_state(state),这会触发无限重渲染循环,完全属于冗余操作。
修复后的代码
父组件(MenuBar)
import './styles/menuBar.css' import HeaderBar from './HeaderBar' import { useEffect, useState } from 'react' function MenuBar() { const [actual_class, set_class] = useState() const Change_class = (value) => { set_class(value) } useEffect(() => { console.log(`当前类名是 ${actual_class}`) }, [actual_class]) return( <div> <HeaderBar throwData={Change_class}/> <div className="wrapper menu_container"> <h1>I'am header bar</h1> </div> </div> ) } export default MenuBar
子组件(HeaderBar)
import './styles/headerBar.css' import { useState, useEffect } from 'react' function HeaderBar(props) { const [state, set_state] = useState() const OnClickHandler = () => { const newState = "oppened" set_state(newState) // 直接传递新值,避免依赖未更新的state props.throwData(newState) } useEffect(() => { console.log(`状态已改为 ${state}`) }, [state]) return( <div className='wrapper header_container'> <ul> <li><h1 className={state === "oppened" ? "green" : "black"}>B</h1></li> <li onClick={OnClickHandler}><span className="material-icons md-18">menu</span></li> </ul> </div> ) } export default HeaderBar
核心修复点
- 直接传递新状态值:在点击事件中先定义新状态值,同时用于更新子组件状态和传递给父组件,绕开React状态更新的异步延迟问题。
- 移除无效的useEffect操作:删除
HeaderBar中useEffect里的set_state(state),消除无限重渲染隐患。 - 修正React规范问题:将子组件中
span的class改为React要求的className。
内容的提问来源于stack exchange,提问作者Emmanuel Medeiros
相关产品推荐
相关产品推荐

