我刚刚尝试了 react 功能组件,它似乎神奇地工作了。在我的组件函数中,我初始化状态并返回 View 。 View 中的操作可以调用组件函数范围内定义的函数,从而更新状态。
我的假设是功能组件的函数仅被调用一次,但惊讶地发现每次发生状态更改时都会调用它。如果此函数初始化状态,并且在每次状态更改时调用它,那么我的状态如何在每次状态更改时不被重置?
这是一个键盘记录器组件,它从输入中获取击键并将其显示在 div 中:
export const KeyLogger = () => {
const [keysLogged, setKeysLogged] = React.useState<string[]>([]);
const logKey = (key: string) => {
setKeysLogged(keysLogged.concat(key));
}
console.log("HERE");
return (
<React.Fragment>
<input onKeyUp={ev => logKey(ev.key)}/>
<br/>
<div>{keysLogged}</div>
</React.Fragment>
);
};
当我使用此组件时,我发现 keysLogged
随着我的输入而增长。
我还看到每次击键都会记录“HERE”。
当我的功能组件的第一行出现初始化每次调用的 keysLogged
时,这怎么可能?
const [keysLogged, setKeysLogged] = React.useState<string[]>([]);
编辑:
使用@Ethan Lipkind 的回复我发现了这个:
There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple useState() calls each get independent local state.
因此,React 根据 useState
的调用顺序知道要使用哪个值。而且因为它使用的是 useState
而不是 createState
,所以如果内存单元位置的值已经存在,react 知道不会重新初始化该值。
当我切换每次调用中初始化 keysLoggedA
和 keysLoggedB
的顺序时,这会产生有趣的影响。
let counter = 0;
export const KeyLogger = () => {
counter++;
let keysLoggedA: any;
let setKeysLoggedA: any;
let keysLoggedB: any;
let setKeysLoggedB: any;
if (counter % 2 === 0) {
[keysLoggedA, setKeysLoggedA] = React.useState<string[]>([]);
[keysLoggedB, setKeysLoggedB] = React.useState<string[]>([]);
} else {
[keysLoggedB, setKeysLoggedB] = React.useState<string[]>([]);
[keysLoggedA, setKeysLoggedA] = React.useState<string[]>([]);
}
const logKey = (key: string) => {
setKeysLoggedA(keysLoggedA.concat(key));
}
console.log("HERE");
return (
<React.Fragment>
<input onKeyUp={ev => logKey(ev.key)}/>
<br/>
<div>{keysLoggedA}</div>
<div>{keysLoggedB}</div>
</React.Fragment>
);
};
即使我只调用 setKeysLoggedA
,您也可以看到 keysLoggedA
和 keysLoggedB
都已更新。
这是因为它完全依赖于调用 useState 的顺序。这是有道理的,我不知道它还能是什么,但很高兴知道魔法是如何运作的。
最佳答案
每次状态更改时,都会触发重新渲染,这就是为什么您会在每次击键时看到日志。由于 useState
Hook 在幕后工作的方式,状态不会在每次函数调用时重新初始化:https://reactjs.org/docs/hooks-state.html
关于javascript - 功能 react 如何不重置状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64121958/