react 函数式组件中,在 func1 函数内调用 func2 ,func2 更新 messages 后,再调用 func2 ,此时 func2 内打印的 messages 值还是个初始值?
场景是使用 openai function call 的时候。
代码如下:
export default function xx(props) {
const { messages, appendMsg } = useMessages(initialMessages);
function func1() {
func2();
}
function func2() {
console.log(messages);
appendMsg({xx});
appendMsg({yy});
func2();
}
return (
<button onClick={func1}>Call func1</button>
);
}
用useRef获取了最新的state值:
const messagesRef = useRef(messages);
useEffect(() => {
messagesRef.current = messages;
}, [messages]);
1
enchilada2020 2023-06-26 14:08:35 +08:00 via Android
你这不无限递归了吗
|
2
ewiglicht 2023-06-26 14:11:14 +08:00
|
3
daydreamcafe 2023-06-26 14:16:35 +08:00
2 楼的文档已经很完整的解释了原理,关于你这个场景,使用回调函数的方式去更新状态可以保证每次的 state 为最新
appendMsg((prevState) => { // ... 在这里做一些状态的改变,之后 return 出想要修改的状态,记得读取的状态要来自 prevState }) |
4
leroy20317 2023-06-26 14:19:49 +08:00 1
useRef
|
5
s609926202 OP @enchilada2020 #1 openai funtion calling 就是递归吧,只有匹配到 function ,就递归
|
6
296727 2023-06-26 14:24:09 +08:00 1
|
7
s609926202 OP @daydreamcafe #3 appendMsg 是第三方库( chatUI )导出的一个方法,只接收新的 msg 对象,貌似做不了回调函数这样的调用。
|
8
Leviathann 2023-06-26 15:15:00 +08:00
message 这个值或者引用是栈上变量,每次重新渲染,函数重新被调用,它的调用栈帧都是新的,也就是说旧的变量一旦捕获就不会随着组件的重新渲染而变更
解决方法就是把它的值放在堆上,用一个不变的引用关系去指向它,在 react 里,这是 ref |
9
Leviathann 2023-06-26 15:17:16 +08:00
另外传入 useEffect 的 callback 是在渲染完成后执行,本意也并不是用来 watch ,你是否需要这个延迟?
|
10
s609926202 OP @Leviathann #9 没懂,哪里加延迟?是 useEffect 里加延迟吗。
|
11
oppt 2023-06-26 17:41:59 +08:00
把 message 作为参数传进 fun2
function func2(messages) { console.log(messages); const newMessages = {xx} appendMsg(newMessages); func2(newMessages); } |
12
s609926202 OP @oppt #11 靠传递参数是不行的
|
13
amlee 2023-06-27 23:23:38 +08:00
不对啊,楼上这么多回答的,你们都清楚 op 代码中的 useMessages 是一个什么样的 hook ?
|
14
magicdawn 2023-07-04 14:36:38 +08:00 via Android
用 useMomoizedFn 以前叫 usePersistFn, 也是社区流产的 useEvent 或 useEventCallback
|
15
s609926202 OP @magicdawn #14 这个也是 ahook 中提供的,为了减少引用库的数量,用 ref 处理了。
|
16
KgM4gLtF0shViDH3 2023-08-08 18:05:55 +08:00
@ewiglicht 你是怎么发现官方的中文文档的,没找到任何切换语言的地方。
|
18
KgM4gLtF0shViDH3 2023-08-10 08:48:04 +08:00
@ewiglicht 还真有,我用英文搜就搜不到。。。
|