【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>
);
}
点击按钮输出:
name Joy
那么为什么延时函数里执行的say()
输出的name
不是最新的Joy
呢?当调用setName给name重新赋值时,组件重新构建,相当于重新执行了一遍Test
函数,里面的局部变量包括name
和say
会再一次创建并且被赋值,此时name
和say
已经是新的值,由于useEffect
的第二个参数为空数组,所以第一入参的函数依然没有改变,其中的say变量指向的还是上一次创建的say
函数(形成了一个闭包),里面保存着上一次的name
值,所以输出还是上一次的值Kidy
。
为什么点击按钮输出的是最新的值Joy
?Test
再次被创建时,构建并返回了最新的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>
);
}
延时函数和点击事件输出的country.current
的值都是最新的值加拿大
,这个又是为什么呢?country
用的是useRef
函数返回值,其返回的是一个引用,赋值的时候是给country
对象属性current
赋值,也就是在Test
函数重新执行的时候country
的指向始终没变,所以无论什么时候什么情况下对同一个引用输出属性值,都是相同的。
函数组件在重新执行时,useState总是返回一个全新的值,useRef总是返回相同的引用
javascriptreact.js
阅读 21更新于 5 分钟前
本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
Juven
115 声望
2 粉丝
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>
);
}
点击按钮输出:
name Joy
那么为什么延时函数里执行的say()
输出的name
不是最新的Joy
呢?当调用setName给name重新赋值时,组件重新构建,相当于重新执行了一遍Test
函数,里面的局部变量包括name
和say
会再一次创建并且被赋值,此时name
和say
已经是新的值,由于useEffect
的第二个参数为空数组,所以第一入参的函数依然没有改变,其中的say变量指向的还是上一次创建的say
函数(形成了一个闭包),里面保存着上一次的name
值,所以输出还是上一次的值Kidy
。
为什么点击按钮输出的是最新的值Joy
?Test
再次被创建时,构建并返回了最新的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>
);
}
延时函数和点击事件输出的country.current
的值都是最新的值加拿大
,这个又是为什么呢?country
用的是useRef
函数返回值,其返回的是一个引用,赋值的时候是给country
对象属性current
赋值,也就是在Test
函数重新执行的时候country
的指向始终没变,所以无论什么时候什么情况下对同一个引用输出属性值,都是相同的。
函数组件在重新执行时,useState总是返回一个全新的值,useRef总是返回相同的引用
以上是 【JS】关于React hooks获取不到最新值的分析 的全部内容, 来源链接: utcz.com/a/105910.html
得票时间