javascript - 功能 react 如何不重置状态?

标签 javascript reactjs

我刚刚尝试了 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 随着我的输入而增长。

enter image description here

我还看到每次击键都会记录“HERE”。

enter image description 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 知道不会重新初始化该值。

当我切换每次调用中初始化 keysLoggedAkeysLoggedB 的顺序时,这会产生有趣的影响。

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,您也可以看到 keysLoggedAkeysLoggedB 都已更新。

enter image description here

这是因为它完全依赖于调用 useState 的顺序。这是有道理的,我不知道它还能是什么,但很高兴知道魔法是如何运作的。

最佳答案

每次状态更改时,都会触发重新渲染,这就是为什么您会在每次击键时看到日志。由于 useState Hook 在幕后工作的方式,状态不会在每次函数调用时重新初始化:https://reactjs.org/docs/hooks-state.html

关于javascript - 功能 react 如何不重置状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64121958/

相关文章:

javascript - 在 onsubmit 代码之后提交表单操作时不遵循

javascript - Link_to 不渲染自定义 Controller 操作的部分内容

javascript - 搜索查询以在 React 中过滤结果

reactjs - 部署到 IIS 后 React 应用程序路由不起作用

reactjs - React Native 中的 react-native run-android

javascript - uncss,.no -'string' 和 .is -'string' 的正则表达式模式

javascript - JSON 对象(如何最初不将整个对象加载到 DOM 上)

javascript - 如何创建具有边框样式的动态响应式四列?

javascript - Hook useState 在不应该记录状态时记录状态。包含示例代码盒

asp.net - .NET Core + React 模板渲染在更改后不会更新