React Hooks转换后未达预期输出:类与函数组件状态差异咨询
React类组件与函数组件状态打印差异的原因分析
核心差异:状态访问机制不同
类组件的逻辑
类组件中,this.state是一个可变的对象引用。不管func2是在哪个阶段被定义的,当它执行时,访问的this.state.user都是组件实例当前最新的状态值。哪怕你是在user还没更新时就定义了func2,等它执行时user已经被改成'ishan',this.state会直接返回最新值,所以打印结果是'ishan'。
函数组件的逻辑
函数组件的状态是通过闭包捕获的——每一次组件渲染都是一个独立的执行上下文,状态值就是当前上下文里的快照。如果func2是在user为null的那次渲染中被创建的(比如组件初始化的第一个渲染周期),那它内部的user就被固定成了null。哪怕之后user更新为'ishan',这个已经创建好的func2不会重新捕获新的状态值,所以打印出来还是null。
代码示例对比
类组件(输出'ishan')
class ClassComp extends React.Component { state = { user: null }; componentDidMount() { this.setState({ user: 'ishan' }); setTimeout(() => this.func2(), 1000); } func2 = () => { console.log(this.state.user); // 'ishan' }; render() { return <div></div>; } }
函数组件(输出null)
function FuncComp() { const [user, setUser] = React.useState(null); React.useEffect(() => { setUser('ishan'); setTimeout(func2, 1000); }, []); const func2 = () => { console.log(user); // null }; return <div></div>; }
函数组件的解决办法
如果想让函数组件里的func2能拿到最新的状态值,可以用useRef来保存状态的最新引用:
function FixedFuncComp() { const [user, setUser] = React.useState(null); const userRef = React.useRef(user); // 每次user更新时同步到ref React.useEffect(() => { userRef.current = user; }, [user]); React.useEffect(() => { setUser('ishan'); setTimeout(() => { console.log(userRef.current); // 'ishan' }, 1000); }, []); return <div></div>; }
内容的提问来源于stack exchange,提问作者Ishan Varshney
相关产品推荐
相关产品推荐

