【JS】关于React hooks获取不到最新值的分析

关于React hooks获取不到最新值的分析

Juven发布于 22 分钟前

有时候获取不到最新的state状态值,如下例子:

import React, { useState, useEffect } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const say = () => {

console.log('name', name);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

return null;

}

结果打印出来的是

name Kidy

所以为什么呢?
我们改一下这个示例,增加能正常获取name值的方式:

import React, { useState, useEffect } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const say = () => {

console.log('name', name);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

// 增加了一个按钮,点击触发say函数的执行

return (

<div>

<button onClick={say}>

按钮

</button>

</div>

);

}

【JS】关于React hooks获取不到最新值的分析

点击按钮输出:

name Joy

那么为什么延时函数里执行的say()输出的name不是最新的Joy呢?当调用setName给name重新赋值时,组件重新构建,相当于重新执行了一遍Test函数,里面的局部变量包括namesay会再一次创建并且被赋值,此时namesay已经是新的值,由于useEffect的第二个参数为空数组,所以第一入参的函数依然没有改变,其中的say变量指向的还是上一次创建的say函数(形成了一个闭包),里面保存着上一次的name值,所以输出还是上一次的值Kidy

为什么点击按钮输出的是最新的值JoyTest再次被创建时,构建并返回了最新的Dom,onClick指向的是当次创建的say函数,也即是包含最新name值的say函数作为button的点击执行函数。

再来看一个案例:

import React, { useState, useEffect, useRef } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const country = useRef('美国');

const say = () => {

console.log('name', name);

console.log('country', country.current);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 这里直接设置为'加拿大'

country.current = '加拿大';

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

return (

<div>

<button onClick={say}>

按钮

</button>

</div>

);

}

【JS】关于React hooks获取不到最新值的分析

延时函数和点击事件输出的country.current的值都是最新的值加拿大,这个又是为什么呢?country用的是useRef函数返回值,其返回的是一个引用,赋值的时候是给country对象属性current赋值,也就是在Test函数重新执行的时候country的指向始终没变,所以无论什么时候什么情况下对同一个引用输出属性值,都是相同的。

函数组件在重新执行时,useState总是返回一个全新的值,useRef总是返回相同的引用

javascriptreact.js

阅读 21更新于 5 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


Jv的程序员之路

从学习中获取,从分享中巩固,从给与中快乐。

avatar

Juven

115 声望

2 粉丝

0 条评论

得票时间

avatar

Juven

115 声望

2 粉丝

宣传栏

有时候获取不到最新的state状态值,如下例子:

import React, { useState, useEffect } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const say = () => {

console.log('name', name);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

return null;

}

结果打印出来的是

name Kidy

所以为什么呢?
我们改一下这个示例,增加能正常获取name值的方式:

import React, { useState, useEffect } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const say = () => {

console.log('name', name);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

// 增加了一个按钮,点击触发say函数的执行

return (

<div>

<button onClick={say}>

按钮

</button>

</div>

);

}

【JS】关于React hooks获取不到最新值的分析

点击按钮输出:

name Joy

那么为什么延时函数里执行的say()输出的name不是最新的Joy呢?当调用setName给name重新赋值时,组件重新构建,相当于重新执行了一遍Test函数,里面的局部变量包括namesay会再一次创建并且被赋值,此时namesay已经是新的值,由于useEffect的第二个参数为空数组,所以第一入参的函数依然没有改变,其中的say变量指向的还是上一次创建的say函数(形成了一个闭包),里面保存着上一次的name值,所以输出还是上一次的值Kidy

为什么点击按钮输出的是最新的值JoyTest再次被创建时,构建并返回了最新的Dom,onClick指向的是当次创建的say函数,也即是包含最新name值的say函数作为button的点击执行函数。

再来看一个案例:

import React, { useState, useEffect, useRef } from 'react';

export default function Test() {

const [name, setName] = useState('Kidy');

const country = useRef('美国');

const say = () => {

console.log('name', name);

console.log('country', country.current);

};

useEffect(() => {

// 设置name的值为Joy

setName('Joy');

// 这里直接设置为'加拿大'

country.current = '加拿大';

// 1s后打印出name的值,理论上name的最新的值为Joy,期望输出Joy

setTimeout(() => {

say();

}, 1000);

}, []);

return (

<div>

<button onClick={say}>

按钮

</button>

</div>

);

}

【JS】关于React hooks获取不到最新值的分析

延时函数和点击事件输出的country.current的值都是最新的值加拿大,这个又是为什么呢?country用的是useRef函数返回值,其返回的是一个引用,赋值的时候是给country对象属性current赋值,也就是在Test函数重新执行的时候country的指向始终没变,所以无论什么时候什么情况下对同一个引用输出属性值,都是相同的。

函数组件在重新执行时,useState总是返回一个全新的值,useRef总是返回相同的引用

以上是 【JS】关于React hooks获取不到最新值的分析 的全部内容, 来源链接: utcz.com/a/105910.html

回到顶部